class Chef::RunList::RunListExpansion
Abstract Base class for expanding a run list. Subclasses must handle
fetching roles from a data source by defining fetch_role
Attributes
Like run list trace but instead of saving the entries as strings it saves their objects The #to_json method uses this list to construct json.
A VersionedRecipeList of recipes. Populated only after expand is called.
The data source passed to the constructor. Not used in this class. In subclasses, this is a Chef::ServerAPI object pre-configured to fetch roles from their correct location.
Public Class Methods
# File lib/chef/run_list/run_list_expansion.rb, line 65 def initialize(environment, run_list_items, source = nil) @environment = environment @missing_roles_with_including_role = Array.new @run_list_items = run_list_items.dup @source = source @default_attrs = Mash.new @override_attrs = Mash.new @recipes = Chef::RunList::VersionedRecipeList.new @applied_roles = {} @run_list_trace = Hash.new { |h, key| h[key] = [] } @better_run_list_trace = Hash.new { |h, key| h[key] = [] } @all_missing_roles = {} @role_errors = {} end
Public Instance Methods
# File lib/chef/run_list/run_list_expansion.rb, line 114 def applied_role?(role_name) @applied_roles.has_key?(role_name) end
# File lib/chef/run_list/run_list_expansion.rb, line 109 def apply_role_attributes(role) @default_attrs = Chef::Mixin::DeepMerge.merge(@default_attrs, role.default_attributes) @override_attrs = Chef::Mixin::DeepMerge.merge(@override_attrs, role.override_attributes) end
# File lib/chef/run_list/run_list_expansion.rb, line 142 def errors @missing_roles_with_including_role.map { |item| item.first } end
Did we find any errors (expanding roles)?
# File lib/chef/run_list/run_list_expansion.rb, line 85 def errors? @missing_roles_with_including_role.length > 0 end
Recurses over the run list items, expanding roles. After this,
recipes
will contain the fully expanded recipe list
# File lib/chef/run_list/run_list_expansion.rb, line 93 def expand # Sure do miss function arity when being recursive expand_run_list_items(@run_list_items) end
In subclasses, this method will fetch the role from the data source.
# File lib/chef/run_list/run_list_expansion.rb, line 127 def fetch_role(name, included_by) raise NotImplementedError end
Fetches and inflates a role
Returns¶ ↑
Chef::Role in most cases false if the role has already been applied nil if the role does not exist
# File lib/chef/run_list/run_list_expansion.rb, line 103 def inflate_role(role_name, included_by) return false if applied_role?(role_name) # Prevent infinite loops applied_role(role_name) fetch_role(role_name, included_by) end
When a role is not found, an error message is logged, but no exception is raised. We do add an entry in the errors collection.
Returns¶ ↑
nil
# File lib/chef/run_list/run_list_expansion.rb, line 135 def role_not_found(name, included_by) Chef::Log.error("Role #{name} (included by '#{included_by}') is in the runlist but does not exist. Skipping expand.") @missing_roles_with_including_role << [name, included_by] @all_missing_roles[name] = true nil end
Returns an array of role names that were expanded; this includes any roles that were in the original, pre-expansion run_list as well as roles processed during expansion. Populated only after expand is called.
# File lib/chef/run_list/run_list_expansion.rb, line 122 def roles @applied_roles.keys end
# File lib/chef/run_list/run_list_expansion.rb, line 150 def to_hash seen_items = { :recipe => {}, :role => {} } { :id => @environment, :run_list => convert_run_list_trace("top level", seen_items) } end
# File lib/chef/run_list/run_list_expansion.rb, line 146 def to_json(*a) Chef::JSONCompat.to_json(to_hash, *a) end
Private Instance Methods
these methods modifies internal state based on arguments, so hide it.
# File lib/chef/run_list/run_list_expansion.rb, line 159 def applied_role(role_name) @applied_roles[role_name] = true end
Recursive helper to decode the non-nested hash form back into a tree
# File lib/chef/run_list/run_list_expansion.rb, line 182 def convert_run_list_trace(base, seen_items) @better_run_list_trace[base].map do |item| skipped = seen_items[item.type][item.name] seen_items[item.type][item.name] = true case item.type when :recipe { :type => "recipe", :name => item.name, :version => item.version, :skipped => !!skipped } when :role error = @role_errors[item.name] missing = @all_missing_roles[item.name] { :type => :role, :name => item.name, :children => (missing || error || skipped) ? [] : convert_run_list_trace(item.to_s, seen_items), :missing => missing, :error => error, :skipped => skipped } end end end
# File lib/chef/run_list/run_list_expansion.rb, line 163 def expand_run_list_items(items, included_by = "top level") if entry = items.shift @run_list_trace[included_by.to_s] << entry.to_s @better_run_list_trace[included_by.to_s] << entry case entry.type when :recipe recipes.add_recipe(entry.name, entry.version) when :role if role = inflate_role(entry.name, included_by) expand_run_list_items(role.run_list_for(@environment).run_list_items, role) apply_role_attributes(role) end end expand_run_list_items(items, included_by) end end