Class: Chef::Runner

Inherits:
Object
  • 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

#lazy, #set_or_return, #validate

Constructor Details

#initialize(run_context) ⇒ Runner


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

def initialize(run_context)
  @run_context = run_context
  @run_context.runner = self
end

Instance Attribute Details

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


125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/chef/runner.rb', line 125

def converge
  # Resolve all lazy/forward references in notifications
  run_context.resource_collection.each(&:resolve_notification_references)

  # Execute each resource.
  run_context.resource_collection.execute_each_resource do |resource|
    unless run_context.resource_collection.unified_mode
      run_all_actions(resource)
    end
  end

  if run_context.resource_collection.unified_mode
    run_context.resource_collection.each { |r| r.resolve_notification_references(true) }
  end

rescue Exception => e
  Chef::Log.info "Running queued delayed notifications before re-raising exception"
  run_delayed_notifications(e)
else
  run_delayed_notifications(nil)
  true
end

#delayed_actionsObject


40
41
42
# File 'lib/chef/runner.rb', line 40

def delayed_actions
  @run_context.delayed_actions
end

#eventsObject


44
45
46
# File 'lib/chef/runner.rb', line 44

def events
  @run_context.events
end

#run_action(resource, action, notification_type = nil, notifying_resource = nil) ⇒ Object

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


54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
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
# File 'lib/chef/runner.rb', line 54

def run_action(resource, action, notification_type = nil, notifying_resource = nil)
  # If there are any before notifications, why-run the resource
  # and notify anyone who needs notifying
  before_notifications = run_context.before_notifications(resource) || []
  unless before_notifications.empty?
    forced_why_run do
      Chef::Log.info("#{resource} running why-run #{action} action to support before action")
      resource.run_action(action, notification_type, notifying_resource)
    end

    if resource.updated_by_last_action?
      before_notifications.each do |notification|
        Chef::Log.info("#{resource} sending #{notification.action} action to #{notification.resource} (before)")
        run_action(notification.resource, notification.action, :before, resource)
      end
      resource.updated_by_last_action(false)
    end
  end

  # Actually run the action for realsies
  resource.run_action(action, notification_type, notifying_resource)

  # 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?
    updated_resources.add(resource.declared_key) # track updated resources for unified_mode
    run_context.immediate_notifications(resource).each do |notification|
      if notification.resource.is_a?(String) && run_context.unified_mode
        Chef::Log.debug("immediate notification from #{resource} to #{notification.resource} is delayed until declaration due to unified_mode")
      else
        Chef::Log.info("#{resource} sending #{notification.action} action to #{notification.resource} (immediate)")
        run_action(notification.resource, notification.action, :immediate, resource)
      end
    end

    run_context.delayed_notifications(resource).each do |notification|
      if notification.resource.is_a?(String)
        # for string resources that have not be declared yet in unified mode we only support notifying the current run_context
        run_context.add_delayed_action(notification)
      else
        # send the notification to the run_context of the receiving resource
        notification.resource.run_context.add_delayed_action(notification)
      end
    end
  end
end

#run_all_actions(resource) ⇒ Object

Runs all of the actions on a given resource. This fires notifications and marks the resource as having been executed by the runner.


107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/chef/runner.rb', line 107

def run_all_actions(resource)
  Array(resource.action).each { |action| run_action(resource, action) }
  if run_context.unified_mode
    run_context.reverse_immediate_notifications(resource).each do |n|
      if updated_resources.include?(n.notifying_resource.declared_key)
        n.resolve_resource_reference(run_context.resource_collection)
        Chef::Log.info("#{resource} sent #{n.action} action to #{n.resource} (immediate at declaration time)")
        run_action(n.resource, n.action, :immediate, n.notifying_resource)
      end
    end
  end
ensure
  resource.executed_by_runner = true
end

#updated_resourcesObject


48
49
50
# File 'lib/chef/runner.rb', line 48

def updated_resources
  @run_context.updated_resources
end