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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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.

[View source]

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

[View source]

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.

[View source]

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

[View source]

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

[View source]

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.

[View source]

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)

[View source]

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

[View source]

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.

[View source]

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

[View source]

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.

[View source]

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)
[View source]

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

[View source]

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

def waiver_collection
  run_context.waiver_collection
end