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.


140
141
142
143
144
145
146
# File 'lib/chef/run_context/cookbook_compiler.rb', line 140

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
107
108
109
110
111
112
113
114
# 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|
    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.


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

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


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/chef/run_context/cookbook_compiler.rb', line 118

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.


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

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


160
161
162
163
164
165
166
# File 'lib/chef/run_context/cookbook_compiler.rb', line 160

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.


194
195
196
# File 'lib/chef/run_context/cookbook_compiler.rb', line 194

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)

189
190
191
# File 'lib/chef/run_context/cookbook_compiler.rb', line 189

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