# class Chef::RunContext

## Chef::RunContext¶ ↑

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

### Attributes

cookbook_collection[R]

Chef::CookbookCollection for this run

definitions[R]

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

delayed_notification_collection[RW]

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

events[R]

Event dispatcher for this run.

immediate_notification_collection[RW]

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

node[R]

Chef::Node object for this run

resource_collection[RW]

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

### Public Class Methods

new(node, cookbook_collection, events) click to toggle source

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. :)

    # 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

      @cookbook_compiler = nil
    end

### Public Instance Methods

delayed_notifications(resource) click to toggle source

    # File lib/chef/run_context.rb, line 122
    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

has_cookbook_file_in_cookbook?(cookbook, cb_file_name) click to toggle source

    # File lib/chef/run_context.rb, line 240
    def has_cookbook_file_in_cookbook?(cookbook, cb_file_name)
      cookbook = cookbook_collection[cookbook]
      cookbook.has_cookbook_file_for_node?(node, cb_file_name)
    end

has_template_in_cookbook?(cookbook, template_name) click to toggle source

Cookbook File Introspection

    # File lib/chef/run_context.rb, line 235
    def has_template_in_cookbook?(cookbook, template_name)
      cookbook = cookbook_collection[cookbook]
      cookbook.has_template_for_node?(node, template_name)
    end

immediate_notifications(resource) click to toggle source

    # File lib/chef/run_context.rb, line 114
    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) click to toggle source

Evaluates the recipes `recipe_names`. Used by DSL::IncludeRecipe

    # File lib/chef/run_context.rb, line 131
    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) click to toggle source

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

    # File lib/chef/run_context.rb, line 86
    def load(run_list_expansion)
      @cookbook_compiler = CookbookCompiler.new(self, run_list_expansion, events)
      @cookbook_compiler.compile
    end

load_recipe(recipe_name) click to toggle source

Evaluates the recipe `recipe_name`. Used by DSL::IncludeRecipe

    # File lib/chef/run_context.rb, line 142
        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 unreachable_cookbook?(cookbook_name) # CHEF-4367
            Chef::Log.warn("MissingCookbookDependency:
    Recipe `#{recipe_name}` is not in the run_list, and cookbook '#{cookbook_name}'
    is not a dependency of any cookbook in the run_list.  To load this recipe,
    first add a dependency on cookbook '#{cookbook_name}' in the cookbook you're
    including it from in that cookbook's metadata.
    ")
          end

          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)
            node.loaded_recipe(cookbook_name, recipe_short_name)
            cookbook = cookbook_collection[cookbook_name]
            cookbook.load_recipe(recipe_short_name, self)
          end
        end

load_recipe_file(recipe_file) click to toggle source

    # File lib/chef/run_context.rb, line 169
    def load_recipe_file(recipe_file)
      if !File.exist?(recipe_file)
        raise Chef::Exceptions::RecipeNotFound, "could not find recipe file #{recipe_file}"
      end

      Chef::Log.debug("Loading Recipe File #{recipe_file}")
      recipe = Chef::Recipe.new('@recipe_files', recipe_file, self)
      recipe.from_file(recipe_file)
      recipe
    end

loaded_attribute(cookbook, attribute_file) click to toggle source

    # File lib/chef/run_context.rb, line 228
    def loaded_attribute(cookbook, attribute_file)
      @loaded_attributes["#{cookbook}::#{attribute_file}"] = true
    end

loaded_attributes() click to toggle source

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”.

    # File lib/chef/run_context.rb, line 208
    def loaded_attributes
      @loaded_attributes.keys
    end

loaded_fully_qualified_attribute?(cookbook, attribute_file) click to toggle source

    # File lib/chef/run_context.rb, line 224
    def loaded_fully_qualified_attribute?(cookbook, attribute_file)
      @loaded_attributes.has_key?("#{cookbook}::#{attribute_file}")
    end

loaded_fully_qualified_recipe?(cookbook, recipe) click to toggle source

    # File lib/chef/run_context.rb, line 212
    def loaded_fully_qualified_recipe?(cookbook, recipe)
      @loaded_recipes.has_key?("#{cookbook}::#{recipe}")
    end

loaded_recipe?(recipe) click to toggle source

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.

    # File lib/chef/run_context.rb, line 219
    def loaded_recipe?(recipe)
      cookbook, recipe_name = Chef::Recipe.parse_recipe_name(recipe)
      loaded_fully_qualified_recipe?(cookbook, recipe_name)
    end

loaded_recipes() click to toggle source

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?

    # File lib/chef/run_context.rb, line 199
    def loaded_recipes
      @loaded_recipes.keys
    end

notifies_delayed(notification) click to toggle source

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

    # File lib/chef/run_context.rb, line 105
    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) click to toggle source

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

    # File lib/chef/run_context.rb, line 94
    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) click to toggle source

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

    # File lib/chef/run_context.rb, line 182
    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

unreachable_cookbook?(cookbook_name) click to toggle source

Delegates to Chef::RunContext::CookbookCompiler#unreachable_cookbook? Used to raise an error when attempting to load a recipe belonging to a cookbook that is not in the dependency graph. See also: CHEF-4367

    # File lib/chef/run_context.rb, line 248
    def unreachable_cookbook?(cookbook_name)
      @cookbook_compiler.unreachable_cookbook?(cookbook_name)
    end