Class: Chef::RunContext

Inherits:
Object show all
Defined in:
lib/chef/run_context.rb,
lib/chef/run_context/cookbook_compiler.rb

Overview

Chef::RunContext

Value object that loads and tracks the context of a Chef run

Defined Under Namespace

Classes: CookbookCompiler

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(node, cookbook_collection, events) ⇒ RunContext

Creates a new Chef::RunContext object and populates its fields. This object gets used by the Chef Server to generate a fully compiled recipe list for a node.

Returns

object<Chef::RunContext>

Duh. :)



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/chef/run_context.rb', line 68

def initialize(node, cookbook_collection, events)
  @node = node
  @cookbook_collection = cookbook_collection
  @resource_collection = Chef::ResourceCollection.new
  @immediate_notification_collection = Hash.new {|h,k| h[k] = []}
  @delayed_notification_collection = Hash.new {|h,k| h[k] = []}
  @definitions = Hash.new
  @loaded_recipes = {}
  @loaded_attributes = {}
  @events = events

  @node.run_context = self
end

Instance Attribute Details

#cookbook_collectionObject (readonly)

Chef::CookbookCollection for this run



38
39
40
# File 'lib/chef/run_context.rb', line 38

def cookbook_collection
  @cookbook_collection
end

#definitionsObject (readonly)

Resource Definitions for this run. Populated when the files in definitions/ are evaluated (this is triggered by #load).



42
43
44
# File 'lib/chef/run_context.rb', line 42

def definitions
  @definitions
end

#delayed_notification_collectionObject

A Hash containing the delayed (end of run) notifications triggered by resources during the converge phase of the chef run.



58
59
60
# File 'lib/chef/run_context.rb', line 58

def delayed_notification_collection
  @delayed_notification_collection
end

#eventsObject (readonly)

Event dispatcher for this run.



61
62
63
# File 'lib/chef/run_context.rb', line 61

def events
  @events
end

#immediate_notification_collectionObject

A Hash containing the immediate notifications triggered by resources during the converge phase of the chef run.



54
55
56
# File 'lib/chef/run_context.rb', line 54

def immediate_notification_collection
  @immediate_notification_collection
end

#nodeObject (readonly)

Chef::Node object for this run



35
36
37
# File 'lib/chef/run_context.rb', line 35

def node
  @node
end

#resource_collectionObject

The Chef::ResourceCollection for this run. Populated by evaluating recipes, which is triggered by #load. (See also: CookbookCompiler)



50
51
52
# File 'lib/chef/run_context.rb', line 50

def resource_collection
  @resource_collection
end

Instance Method Details

#delayed_notifications(resource) ⇒ Object



120
121
122
123
124
125
126
# File 'lib/chef/run_context.rb', line 120

def delayed_notifications(resource)
  if resource.instance_of?(Chef::Resource)
    return @delayed_notification_collection[resource.name]
  else
    return @delayed_notification_collection[resource.to_s]
  end
end

#immediate_notifications(resource) ⇒ Object



112
113
114
115
116
117
118
# File 'lib/chef/run_context.rb', line 112

def immediate_notifications(resource)
  if resource.instance_of?(Chef::Resource)
    return @immediate_notification_collection[resource.name]
  else
    return @immediate_notification_collection[resource.to_s]
  end
end

#include_recipe(*recipe_names) ⇒ Object

Evaluates the recipes recipe_names. Used by DSL::IncludeRecipe



129
130
131
132
133
134
135
136
137
# File 'lib/chef/run_context.rb', line 129

def include_recipe(*recipe_names)
  result_recipes = Array.new
  recipe_names.flatten.each do |recipe_name|
    if result = load_recipe(recipe_name)
      result_recipes << result
    end
  end
  result_recipes
end

#load(run_list_expansion) ⇒ Object

Triggers the compile phase of the chef run. Implemented by Chef::RunContext::CookbookCompiler



84
85
86
87
# File 'lib/chef/run_context.rb', line 84

def load(run_list_expansion)
  compiler = CookbookCompiler.new(self, run_list_expansion, events)
  compiler.compile
end

#load_recipe(recipe_name) ⇒ Object

Evaluates the recipe recipe_name. Used by DSL::IncludeRecipe



140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/chef/run_context.rb', line 140

def load_recipe(recipe_name)
  Chef::Log.debug("Loading Recipe #{recipe_name} via include_recipe")

  cookbook_name, recipe_short_name = Chef::Recipe.parse_recipe_name(recipe_name)
  if loaded_fully_qualified_recipe?(cookbook_name, recipe_short_name)
    Chef::Log.debug("I am not loading #{recipe_name}, because I have already seen it.")
    false
  else
    loaded_recipe(cookbook_name, recipe_short_name)

    cookbook = cookbook_collection[cookbook_name]
    cookbook.load_recipe(recipe_short_name, self)
  end
end

#loaded_attribute(cookbook, attribute_file) ⇒ Object



203
204
205
# File 'lib/chef/run_context.rb', line 203

def loaded_attribute(cookbook, attribute_file)
  @loaded_attributes["#{cookbook}::#{attribute_file}"] = true
end

#loaded_attributesObject

An Array of all attributes files that have been loaded. Stored internally using a Hash, so order is not preserved on ruby 1.8.

Attribute file names are given in fully qualified form, e.g., “nginx::default” instead of “nginx”.



183
184
185
# File 'lib/chef/run_context.rb', line 183

def loaded_attributes
  @loaded_attributes.keys
end

#loaded_fully_qualified_attribute?(cookbook, attribute_file) ⇒ Boolean

Returns:

  • (Boolean)


199
200
201
# File 'lib/chef/run_context.rb', line 199

def loaded_fully_qualified_attribute?(cookbook, attribute_file)
  @loaded_attributes.has_key?("#{cookbook}::#{attribute_file}")
end

#loaded_fully_qualified_recipe?(cookbook, recipe) ⇒ Boolean

Returns:

  • (Boolean)


187
188
189
# File 'lib/chef/run_context.rb', line 187

def loaded_fully_qualified_recipe?(cookbook, recipe)
  @loaded_recipes.has_key?("#{cookbook}::#{recipe}")
end

#loaded_recipe?(recipe) ⇒ Boolean

Returns true if recipe has been loaded, false otherwise. Default recipe names are expanded, so ‘loaded_recipe?(“nginx”)` and `loaded_recipe?(“nginx::default”)` are valid and give identical results.

Returns:

  • (Boolean)


194
195
196
197
# File 'lib/chef/run_context.rb', line 194

def loaded_recipe?(recipe)
  cookbook, recipe_name = Chef::Recipe.parse_recipe_name(recipe)
  loaded_fully_qualified_recipe?(cookbook, recipe_name)
end

#loaded_recipesObject

An Array of all recipes that have been loaded. This is stored internally as a Hash, so ordering is not preserved when using ruby 1.8.

Recipe names are given in fully qualified form, e.g., the recipe “nginx” will be given as “nginx::default”

To determine if a particular recipe has been loaded, use #loaded_recipe?



174
175
176
# File 'lib/chef/run_context.rb', line 174

def loaded_recipes
  @loaded_recipes.keys
end

#notifies_delayed(notification) ⇒ Object

Adds a delayed notification to the delayed_notification_collection. The notification should be a Chef::Resource::Notification or duck type.



103
104
105
106
107
108
109
110
# File 'lib/chef/run_context.rb', line 103

def notifies_delayed(notification)
  nr = notification.notifying_resource
  if nr.instance_of?(Chef::Resource)
    @delayed_notification_collection[nr.name] << notification
  else
    @delayed_notification_collection[nr.to_s] << notification
  end
end

#notifies_immediately(notification) ⇒ Object

Adds an immediate notification to the immediate_notification_collection. The notification should be a Chef::Resource::Notification or duck type.



92
93
94
95
96
97
98
99
# File 'lib/chef/run_context.rb', line 92

def notifies_immediately(notification)
  nr = notification.notifying_resource
  if nr.instance_of?(Chef::Resource)
    @immediate_notification_collection[nr.name] << notification
  else
    @immediate_notification_collection[nr.to_s] << notification
  end
end

#resolve_attribute(cookbook_name, attr_file_name) ⇒ Object

Looks up an attribute file given the cookbook_name and attr_file_name. Used by DSL::IncludeAttribute



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

def resolve_attribute(cookbook_name, attr_file_name)
  cookbook = cookbook_collection[cookbook_name]
  raise Chef::Exceptions::CookbookNotFound, "could not find cookbook #{cookbook_name} while loading attribute #{name}" unless cookbook

  attribute_filename = cookbook.attribute_filenames_by_short_filename[attr_file_name]
  raise Chef::Exceptions::AttributeNotFound, "could not find filename for attribute #{attr_file_name} in cookbook #{cookbook_name}" unless attribute_filename

  attribute_filename
end