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.



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

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_contextObject (readonly)

Returns the value of attribute run_context.



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

def run_context
  @run_context
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

  • Compliance Profiles/Waivers

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



102
103
104
105
106
107
108
109
110
# File 'lib/chef/run_context/cookbook_compiler.rb', line 102

def compile
  compile_libraries
  compile_ohai_plugins
  compile_compliance
  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.



194
195
196
197
198
199
200
# File 'lib/chef/run_context/cookbook_compiler.rb', line 194

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_complianceObject

Loads the compliance segment files from the cookbook into the collections hanging off of the run_context, for later use in the compliance phase inspec run.



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
# File 'lib/chef/run_context/cookbook_compiler.rb', line 171

def compile_compliance
  events.compliance_load_start
  events.profiles_load_start
  cookbook_order.each do |cookbook|
    load_profiles_from_cookbook(cookbook)
  end
  events.profiles_load_complete
  events.inputs_load_start
  cookbook_order.each do |cookbook|
    load_inputs_from_cookbook(cookbook)
  end
  events.inputs_load_complete
  events.waivers_load_start
  cookbook_order.each do |cookbook|
    load_waivers_from_cookbook(cookbook)
  end
  events.waivers_load_complete
  events.compliance_load_complete
end

#compile_librariesObject

Loads library files from cookbooks according to #cookbook_order.



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/chef/run_context/cookbook_compiler.rb', line 130

def compile_libraries
  events.library_load_start(count_files_by_segment(:libraries))
  cookbook_order.each do |cookbook|
    eager_load_libraries = cookbook_collection[cookbook]..eager_load_libraries
    if eager_load_libraries == true # actually true, not truthy
      load_libraries_from_cookbook(cookbook)
    else
      $LOAD_PATH.unshift File.expand_path("libraries", cookbook_collection[cookbook].root_dir)
      if eager_load_libraries # we have a String or Array<String> and not false
        load_libraries_from_cookbook(cookbook, eager_load_libraries)
      end
    end
  end
  events.library_load_complete
end

#compile_lwrpsObject

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



204
205
206
207
208
209
210
211
# File 'lib/chef/run_context/cookbook_compiler.rb', line 204

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



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/chef/run_context/cookbook_compiler.rb', line 148

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.



223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'lib/chef/run_context/cookbook_compiler.rb', line 223

def compile_recipes
  events.recipe_load_start(run_list_expansion.recipes.size)
  run_list_expansion.recipes.each do |recipe|

    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
  events.recipe_load_complete
end

#compile_resource_definitionsObject

Loads resource definitions according to #cookbook_order



214
215
216
217
218
219
220
# File 'lib/chef/run_context/cookbook_compiler.rb', line 214

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



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

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.



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

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)



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

def definitions
  run_context.definitions
end

#input_collectionObject

The global input_collection hanging off of the run_context, used by compile_compliance and the compliance phase that runs inspec



75
76
77
# File 'lib/chef/run_context/cookbook_compiler.rb', line 75

def input_collection
  run_context.input_collection
end

#nodeObject

Chef::Node object for the current run.



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

def node
  run_context.node
end

#profile_collectionObject

The global profile_collection hanging off of the run_context, used by compile_compliance and the compliance phase that runs inspec



84
85
86
# File 'lib/chef/run_context/cookbook_compiler.rb', line 84

def profile_collection
  run_context.profile_collection
end

#reachable_cookbooksObject

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



248
249
250
# File 'lib/chef/run_context/cookbook_compiler.rb', line 248

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)


243
244
245
# File 'lib/chef/run_context/cookbook_compiler.rb', line 243

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

#waiver_collectionObject

The global waiver_collection hanging off of the run_context, used by compile_compliance and the compliance phase that runs inspec



66
67
68
# File 'lib/chef/run_context/cookbook_compiler.rb', line 66

def waiver_collection
  run_context.waiver_collection
end