summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom May <thom@chef.io>2017-04-05 11:49:51 +0100
committerThom May <thom@chef.io>2017-04-05 18:17:38 +0100
commit5c86ade466a38536186218009e32bb4db1ab3c92 (patch)
treed6e93d25ab4736a9d6f3c338971c56302c3f7708
parenta9d0cfb3bcb995d60e096a755e4e58fa47f40047 (diff)
downloadchef-tm/ohai_plugins_2.tar.gz
RFC 59: Load Ohai pluginstm/ohai_plugins_2
This adds a new phase in the compilation of the run context. Signed-off-by: Thom May <thom@chef.io>
-rw-r--r--Gemfile.lock2
-rw-r--r--chef-config/lib/chef-config/config.rb4
-rw-r--r--lib/chef/event_dispatch/base.rb16
-rw-r--r--lib/chef/node.rb4
-rw-r--r--lib/chef/run_context/cookbook_compiler.rb35
-rw-r--r--spec/integration/client/client_spec.rb33
6 files changed, 93 insertions, 1 deletions
diff --git a/Gemfile.lock b/Gemfile.lock
index 4482a7b5ad..1c7e8bf277 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -37,7 +37,7 @@ GIT
GIT
remote: https://github.com/chef/ohai.git
- revision: 6bb6e8cf30118b104dbcffaea17ffb1644aee2cc
+ revision: daeb73c1089d8b611bc5fde3bfddddad28f304eb
specs:
ohai (13.0.0)
chef-config (>= 12.5.0.alpha.1, < 14)
diff --git a/chef-config/lib/chef-config/config.rb b/chef-config/lib/chef-config/config.rb
index b4bb6b76ab..57f55fdce4 100644
--- a/chef-config/lib/chef-config/config.rb
+++ b/chef-config/lib/chef-config/config.rb
@@ -450,6 +450,10 @@ module ChefConfig
# most of our testing scenarios)
default :minimal_ohai, false
+ # When consuming Ohai plugins from cookbook segments, we place those plugins in this directory.
+ # Subsequent chef client runs will wipe and re-populate the directory to ensure cleanliness
+ default(:ohai_segment_plugin_path) { PathHelper.join(config_dir, "ohai", "cookbook_plugins") }
+
###
# Policyfile Settings
#
diff --git a/lib/chef/event_dispatch/base.rb b/lib/chef/event_dispatch/base.rb
index 926bbe24b5..0f8013f114 100644
--- a/lib/chef/event_dispatch/base.rb
+++ b/lib/chef/event_dispatch/base.rb
@@ -195,6 +195,22 @@ class Chef
def lwrp_load_complete
end
+ # Called when an ohai plugin file loading starts
+ def ohai_plugin_load_start(file_count)
+ end
+
+ # Called when an ohai plugin file has been loaded
+ def ohai_plugin_file_loaded(path)
+ end
+
+ # Called when an ohai plugin file has an error on load.
+ def ohai_plugin_file_load_failed(path, exception)
+ end
+
+ # Called when an ohai plugin file loading has finished
+ def ohai_plugin_load_complete
+ end
+
# Called before attribute files are loaded
def attribute_load_start(attribute_file_count)
end
diff --git a/lib/chef/node.rb b/lib/chef/node.rb
index 92bdb5887b..549bde0dbb 100644
--- a/lib/chef/node.rb
+++ b/lib/chef/node.rb
@@ -338,6 +338,10 @@ class Chef
automatic[:platform_version] = version
end
+ def consume_ohai_data(ohai_data)
+ self.automatic_attrs = Chef::Mixin::DeepMerge.merge(automatic_attrs, ohai_data)
+ end
+
# Consumes the combined run_list and other attributes in +attrs+
def consume_attributes(attrs)
normal_attrs_to_merge = consume_run_list(attrs)
diff --git a/lib/chef/run_context/cookbook_compiler.rb b/lib/chef/run_context/cookbook_compiler.rb
index 94635be03d..02ee2e3519 100644
--- a/lib/chef/run_context/cookbook_compiler.rb
+++ b/lib/chef/run_context/cookbook_compiler.rb
@@ -57,6 +57,7 @@ class Chef
# Run the compile phase of the chef run. Loads files in the following order:
# * Libraries
+ # * Ohai
# * Attributes
# * LWRPs
# * Resource Definitions
@@ -69,6 +70,7 @@ class Chef
# #cookbook_order for more information.
def compile
compile_libraries
+ compile_ohai_plugins
compile_attributes
compile_lwrps
compile_resource_definitions
@@ -101,6 +103,26 @@ class Chef
@events.library_load_complete
end
+ # Loads Ohai Plugins from cookbooks, and ensure any old ones are
+ # properly cleaned out
+ 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
+ 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
+
# 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.
@@ -226,6 +248,19 @@ class Chef
raise
end
+ def load_ohai_plugins_from_cookbook(cookbook_name)
+ target = Chef::Config[:ohai_segment_plugin_path]
+ files_in_cookbook_by_segment(cookbook_name, :ohai).each do |filename|
+ next unless File.extname(filename) == ".rb"
+
+ Chef::Log.debug "Loading Ohai plugin: #{filename} from #{cookbook_name}"
+ target_name = File.join(target, cookbook_name.to_s, File.basename(filename))
+
+ FileUtils.mkdir_p(File.dirname(target_name))
+ FileUtils.cp(filename, target_name)
+ end
+ end
+
def load_resource_definitions_from_cookbook(cookbook_name)
files_in_cookbook_by_segment(cookbook_name, :definitions).each do |filename|
begin
diff --git a/spec/integration/client/client_spec.rb b/spec/integration/client/client_spec.rb
index 2a31638c0f..1cd74a6fd1 100644
--- a/spec/integration/client/client_spec.rb
+++ b/spec/integration/client/client_spec.rb
@@ -465,6 +465,39 @@ end
end
end
+ when_the_repository "has a cookbook with an ohai plugin" do
+ before do
+ file "cookbooks/x/recipes/default.rb", <<-RECIPE
+file #{path_to('tempfile.txt').inspect} do
+ content node["english"]["version"]
+end
+ RECIPE
+
+ file "cookbooks/x/ohai/english.rb", <<-OHAI
+ Ohai.plugin(:English) do
+ provides 'english'
+
+ collect_data do
+ english Mash.new
+ english[:version] = "2014"
+ end
+ end
+ OHAI
+
+ file "config/client.rb", <<EOM
+local_mode true
+cookbook_path "#{path_to('cookbooks')}"
+EOM
+ end
+
+ it "should run the ohai plugin" do
+ result = shell_out("#{chef_client} -l debug -c \"#{path_to('config/client.rb')}\" -o 'x::default' --no-fork", :cwd => chef_dir)
+ result.error!
+
+ expect(IO.read(path_to("tempfile.txt"))).to eq("2014")
+ end
+ end
+
# Fails on appveyor, but works locally on windows and on windows hosts in Ci.
context "when using recipe-url", :skip_appveyor do
before(:each) do