class Chef::ActionCollection
Attributes
Public Class Methods
# File lib/chef/action_collection.rb, line 90 def initialize(events, run_context = nil, action_records = []) @action_records = action_records @pending_updates = [] @consumers = [] @events = events @run_context = run_context end
Public Instance Methods
End of an unsuccessful converge used to fire off detect_unprocessed_resources.
(see EventDispatch::Base#)
# File lib/chef/action_collection.rb, line 146 def converge_failed(exception) return if consumers.empty? detect_unprocessed_resources end
This hook gives us the run_context
immediately after it is created so that we can wire up this object to it.
This also causes the action_collection_registration event to fire, all consumers that have not yet registered with the action_collection must register via this callback. This is the latest point before resources actually start to get evaluated.
(see EventDispatch::Base#)
# File lib/chef/action_collection.rb, line 126 def cookbook_compilation_start(run_context) run_context.action_collection = self # fire the action_colleciton_registration hook after cookbook_compilation_start -- last chance for consumers to register run_context.events.enqueue(:action_collection_registration, self) @run_context = run_context end
Allows getting at the action_records
collection filtered by nesting level and status.
TODO: filtering by resource type+name
@return [Chef::ActionCollection]
# File lib/chef/action_collection.rb, line 106 def filtered_collection(max_nesting: nil, up_to_date: true, skipped: true, updated: true, failed: true, unprocessed: true) subrecords = action_records.select do |rec| ( max_nesting.nil? || rec.nesting_level <= max_nesting ) && ( rec.status == :up_to_date && up_to_date || rec.status == :skipped && skipped || rec.status == :updated && updated || rec.status == :failed && failed || rec.status == :unprocessed && unprocessed ) end self.class.new(events, run_context, subrecords) end
Consumers must call register – either directly or through the action_collection_registration hook. If nobody has registered any interest, then no action tracking will be done.
@params object [Object] callers should call with `self`
# File lib/chef/action_collection.rb, line 138 def register(object) consumers << object end
Hook to start processing a resource. May be called within processing of an outer resource so the pending_updates
array forms a stack that sub-resources are popped onto and off of. This is always called.
(see EventDispatch::Base#)
# File lib/chef/action_collection.rb, line 157 def resource_action_start(new_resource, action, notification_type = nil, notifier = nil) return if consumers.empty? pending_updates << ActionRecord.new(new_resource, action, pending_updates.length) end
Hook called after an action is completed. This is always called, even if the action fails.
(see EventDispatch::Base#)
# File lib/chef/action_collection.rb, line 214 def resource_completed(new_resource) return if consumers.empty? current_record.elapsed_time = new_resource.elapsed_time # Verify if the resource has sensitive data and create a new blank resource with only # the name so we can report it back without sensitive data # XXX?: what about sensitive data in the current_resource? # FIXME: this needs to be display-logic if current_record.new_resource.sensitive klass = current_record.new_resource.class resource_name = current_record.new_resource.name current_record.new_resource = klass.new(resource_name) end action_records << pending_updates.pop end
Hook called after a resource is loaded. If load_current_resource fails, this hook will not be called and current_resource will be nil, and the resource_failed
hook will be called.
(see EventDispatch::Base#)
# File lib/chef/action_collection.rb, line 167 def resource_current_state_loaded(new_resource, action, current_resource) return if consumers.empty? current_record.current_resource = current_resource end
Hook called after an action fails.
(see EventDispatch::Base#)
# File lib/chef/action_collection.rb, line 204 def resource_failed(new_resource, action, exception) return if consumers.empty? current_record.status = :failed current_record.exception = exception end
Hook called after an action is determined to be skipped due to a conditional.
(see EventDispatch::Base#)
# File lib/chef/action_collection.rb, line 185 def resource_skipped(resource, action, conditional) return if consumers.empty? current_record.status = :skipped current_record.conditional = conditional end
Hook called after an action is determined to be up to date.
(see EventDispatch::Base#)
# File lib/chef/action_collection.rb, line 176 def resource_up_to_date(new_resource, action) return if consumers.empty? current_record.status = :up_to_date end
Hook called after an action modifies the system and is marked updated.
(see EventDispatch::Base#)
# File lib/chef/action_collection.rb, line 195 def resource_updated(new_resource, action) return if consumers.empty? current_record.status = :updated end
Private Instance Methods
@return [Chef::ActionCollection::ActionRecord] the current record we are working on at the top of the stack
# File lib/chef/action_collection.rb, line 234 def current_record pending_updates[-1] end
If the chef-client run fails in the middle, we are left with a half-completed resource_collection, this method is responsible for adding all of the resources which have not yet been touched. They are marked as being “unprocessed”.
# File lib/chef/action_collection.rb, line 242 def detect_unprocessed_resources run_context.resource_collection.all_resources.select { |resource| resource.executed_by_runner == false }.each do |resource| Array(resource.action).each do |action| record = ActionRecord.new(resource, action, 0) record.status = :unprocessed action_records << record end end end