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.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_h 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_h, *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 161 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 184 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 165 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