Class: Chef::Runner

Inherits:
Object show all
Includes:
Mixin::ParamsValidate
Defined in:
lib/chef/runner.rb

Overview

Chef::Runner

This class is responsible for executing the steps in a Chef run.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Mixin::ParamsValidate

#set_or_return, #validate

Constructor Details

#initialize(run_context) ⇒ Runner

Returns a new instance of Runner



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

def initialize(run_context)
  @run_context      = run_context
  @delayed_actions  = []
end

Instance Attribute Details

#delayed_actionsObject (readonly)

Returns the value of attribute delayed_actions



33
34
35
# File 'lib/chef/runner.rb', line 33

def delayed_actions
  @delayed_actions
end

#run_contextObject (readonly)

Returns the value of attribute run_context



31
32
33
# File 'lib/chef/runner.rb', line 31

def run_context
  @run_context
end

Instance Method Details

#convergeObject

Iterates over the resource_collection in the run_context calling run_action for each resource in turn.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/chef/runner.rb', line 69

def converge
  # Resolve all lazy/forward references in notifications
  run_context.resource_collection.each do |resource|
    resource.resolve_notification_references
  end

  # Execute each resource.
  run_context.resource_collection.execute_each_resource do |resource|
    begin
      Chef::Log.debug("Processing #{resource} on #{run_context.node.name}")

      # Execute each of this resource's actions.
      Array(resource.action).each {|action| run_action(resource, action)}
    rescue => e
      Chef::Log.error("#{resource} (#{resource.source_line}) had an error:\n#{e}\n#{e.backtrace.join("\n")}")
      if resource.retries > 0
        resource.retries -= 1
        Chef::Log.info("Retrying execution of #{resource}, #{resource.retries} attempt(s) left")
        sleep resource.retry_delay
        retry
      end
      raise e unless resource.ignore_failure
    end
  end

  # Run all our :delayed actions
  delayed_actions.each do |notification|
    Chef::Log.info( "#{notification.notifying_resource} sending #{notification.action}"\
                    " action to #{notification.resource} (delayed)")
    # Struct of resource/action to call
    run_action(notification.resource, notification.action)
  end

  true
end

#run_action(resource, action) ⇒ Object

Determine the appropriate provider for the given resource, then execute it.



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/chef/runner.rb', line 44

def run_action(resource, action)
  resource.run_action(action)

  # Execute any immediate and queue up any delayed notifications
  # associated with the resource, but only if it was updated *this time*
  # we ran an action on it.
  if resource.updated_by_last_action?
    resource.immediate_notifications.each do |notification|
      Chef::Log.info("#{resource} sending #{notification.action} action to #{notification.resource} (immediate)")
      run_action(notification.resource, notification.action)
    end

    resource.delayed_notifications.each do |notification|
      if delayed_actions.any? { |existing_notification| existing_notification.duplicates?(notification) }
        Chef::Log.info( "#{resource} not queuing delayed action #{notification.action} on #{notification.resource}"\
                        " (delayed), as it's already been queued")
      else
        delayed_actions << notification
      end
    end
  end
end