Class: Chef::RunContext::CookbookCompiler

Inherits:
Object
  • Object
show all
Defined in:
lib/chef/run_context/cookbook_compiler.rb

Overview

Implements the compile phase of the chef run by loading/eval-ing files from cookbooks in the correct order and in the correct context.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(run_context, run_list_expansion, events) ⇒ CookbookCompiler

Returns a new instance of CookbookCompiler.



36
37
38
39
40
41
42
# File 'lib/chef/run_context/cookbook_compiler.rb', line 36

def initialize(run_context, run_list_expansion, events)
  @run_context = run_context
  @events = events
  @run_list_expansion = run_list_expansion
  @cookbook_order = nil
  @logger = run_context.logger.with_child(subsystem: "cookbook_compiler")
end

Instance Attribute Details

#eventsObject (readonly)

Returns the value of attribute events.



32
33
34
# File 'lib/chef/run_context/cookbook_compiler.rb', line 32

def events
  @events
end

#loggerObject (readonly)

Returns the value of attribute logger.



34
35
36
# File 'lib/chef/run_context/cookbook_compiler.rb', line 34

def logger
  @logger
end

#run_list_expansionObject (readonly)

Returns the value of attribute run_list_expansion.



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

def run_list_expansion
  @run_list_expansion
end

Instance Method Details

#compileObject

Run the compile phase of the chef run. Loads files in the following order:

  • Libraries

  • Ohai

  • Attributes

  • LWRPs

  • Resource Definitions

  • Recipes

Recipes are loaded in precisely the order specified by the expanded run_list.

Other files are loaded in an order derived from the expanded run_list and the dependencies declared by cookbooks’ metadata. See #cookbook_order for more information.



73
74
75
76
77
78
79
80
# File 'lib/chef/run_context/cookbook_compiler.rb', line 73

def compile
  compile_libraries
  compile_ohai_plugins
  compile_attributes
  compile_lwrps
  compile_resource_definitions
  compile_recipes
end

#compile_attributesObject

Loads attributes files from cookbooks. Attributes files are loaded according to #cookbook_order; within a cookbook, default.rb is loaded first, then the remaining attributes files in lexical sort order.



132
133
134
135
136
137
138
# File 'lib/chef/run_context/cookbook_compiler.rb', line 132

def compile_attributes
  @events.attribute_load_start(count_files_by_segment(:attributes, "attributes.rb"))
  cookbook_order.each do |cookbook|
    load_attributes_from_cookbook(cookbook)
  end
  @events.attribute_load_complete
end

#compile_librariesObject

Loads library files from cookbooks according to #cookbook_order.



100
101
102
103
104
105
106
# File 'lib/chef/run_context/cookbook_compiler.rb', line 100

def compile_libraries
  @events.library_load_start(count_files_by_segment(:libraries))
  cookbook_order.each do |cookbook|
    load_libraries_from_cookbook(cookbook)
  end
  @events.library_load_complete
end

#compile_lwrpsObject

Loads LWRPs according to #cookbook_order. Providers are loaded before resources on a cookbook-wise basis.



142
143
144
145
146
147
148
149
# File 'lib/chef/run_context/cookbook_compiler.rb', line 142

def compile_lwrps
  lwrp_file_count = count_files_by_segment(:providers) + count_files_by_segment(:resources)
  @events.lwrp_load_start(lwrp_file_count)
  cookbook_order.each do |cookbook|
    load_lwrps_from_cookbook(cookbook)
  end
  @events.lwrp_load_complete
end

#compile_ohai_pluginsObject

Loads Ohai Plugins from cookbooks, and ensure any old ones are properly cleaned out



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/chef/run_context/cookbook_compiler.rb', line 110

def compile_ohai_plugins
  ohai_plugin_count = count_files_by_segment(:ohai)
  @events.ohai_plugin_load_start(ohai_plugin_count)
  FileUtils.rm_rf(Chef::Config[:ohai_segment_plugin_path])

  cookbook_order.each do |cookbook|
    load_ohai_plugins_from_cookbook(cookbook)
  end

  # Doing a full ohai system check is costly, so only do so if we've loaded additional plugins
  if ohai_plugin_count > 0
    # FIXME(log): figure out what the ohai logger looks like here
    ohai = Ohai::System.new.run_additional_plugins(Chef::Config[:ohai_segment_plugin_path])
    node.consume_ohai_data(ohai)
  end

  @events.ohai_plugin_load_complete
end

#compile_recipesObject

Iterates over the expanded run_list, loading each recipe in turn.



161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/chef/run_context/cookbook_compiler.rb', line 161

def compile_recipes
  @events.recipe_load_start(run_list_expansion.recipes.size)
  run_list_expansion.recipes.each do |recipe|
    begin
      path = resolve_recipe(recipe)
      @run_context.load_recipe(recipe)
      @events.recipe_file_loaded(path, recipe)
    rescue Chef::Exceptions::RecipeNotFound => e
      @events.recipe_not_found(e)
      raise
    rescue Exception => e
      @events.recipe_file_load_failed(path, e, recipe)
      raise
    end
  end
  @events.recipe_load_complete
end

#compile_resource_definitionsObject

Loads resource definitions according to #cookbook_order



152
153
154
155
156
157
158
# File 'lib/chef/run_context/cookbook_compiler.rb', line 152

def compile_resource_definitions
  @events.definition_load_start(count_files_by_segment(:definitions))
  cookbook_order.each do |cookbook|
    load_resource_definitions_from_cookbook(cookbook)
  end
  @events.definition_load_complete
end

#cookbook_collectionObject

Chef::CookbookCollection object for the current run



50
51
52
# File 'lib/chef/run_context/cookbook_compiler.rb', line 50

def cookbook_collection
  @run_context.cookbook_collection
end

#cookbook_orderObject

Extracts the cookbook names from the expanded run list, then iterates over the list, recursing through dependencies to give a run_list ordered array of cookbook names with no duplicates. Dependencies appear before the cookbook(s) that depend on them.



86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/chef/run_context/cookbook_compiler.rb', line 86

def cookbook_order
  @cookbook_order ||= begin
    ordered_cookbooks = []
    seen_cookbooks = {}
    run_list_expansion.recipes.each do |recipe|
      cookbook = Chef::Recipe.parse_recipe_name(recipe).first
      add_cookbook_with_deps(ordered_cookbooks, seen_cookbooks, cookbook)
    end
    logger.debug("Cookbooks to compile: #{ordered_cookbooks.inspect}")
    ordered_cookbooks
  end
end

#definitionsObject

Resource Definitions from the compiled cookbooks. This is populated by calling #compile_resource_definitions (which is called by #compile)



56
57
58
# File 'lib/chef/run_context/cookbook_compiler.rb', line 56

def definitions
  @run_context.definitions
end

#nodeObject

Chef::Node object for the current run.



45
46
47
# File 'lib/chef/run_context/cookbook_compiler.rb', line 45

def node
  @run_context.node
end

#reachable_cookbooksObject

All cookbooks in the dependency graph, returned as a Set.



186
187
188
# File 'lib/chef/run_context/cookbook_compiler.rb', line 186

def reachable_cookbooks
  @reachable_cookbooks ||= Set.new(cookbook_order)
end

#unreachable_cookbook?(cookbook_name) ⇒ Boolean

Whether or not a cookbook is reachable from the set of cookbook given by the run_list plus those cookbooks’ dependencies.

Returns:

  • (Boolean)


181
182
183
# File 'lib/chef/run_context/cookbook_compiler.rb', line 181

def unreachable_cookbook?(cookbook_name)
  !reachable_cookbooks.include?(cookbook_name)
end