summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorClaire McQuin <claire@opscode.com>2013-09-03 14:24:12 -0700
committerClaire McQuin <claire@opscode.com>2013-09-03 14:53:08 -0700
commitbf6f552c3c70ef836151ae832efde121c3222944 (patch)
treee4f8912b80605c52192d30745d060ccb650d29d4 /lib
parentff149f9a1ea45f63bf785bd3ccc6d8e9e7d87739 (diff)
downloadohai-bf6f552c3c70ef836151ae832efde121c3222944.tar.gz
Ohai::Runner class for running plugins, add run_plugins to Ohai::System to run loaded plugins
Diffstat (limited to 'lib')
-rw-r--r--lib/ohai/plugins/chef.rb2
-rw-r--r--lib/ohai/plugins/darwin/kernel.rb3
-rw-r--r--lib/ohai/plugins/kernel.rb3
-rw-r--r--lib/ohai/runner.rb93
-rw-r--r--lib/ohai/system.rb36
5 files changed, 122 insertions, 15 deletions
diff --git a/lib/ohai/plugins/chef.rb b/lib/ohai/plugins/chef.rb
index b9b6872e..bbe16b46 100644
--- a/lib/ohai/plugins/chef.rb
+++ b/lib/ohai/plugins/chef.rb
@@ -19,7 +19,7 @@
require 'chef/version'
Ohai.plugin do
- provides "chef"
+ provides "chef_packages/chef"
collect_data do
self[:chef_packages] = Mash.new unless self[:chef_packages]
diff --git a/lib/ohai/plugins/darwin/kernel.rb b/lib/ohai/plugins/darwin/kernel.rb
index ff8633aa..14f8bf6d 100644
--- a/lib/ohai/plugins/darwin/kernel.rb
+++ b/lib/ohai/plugins/darwin/kernel.rb
@@ -17,7 +17,8 @@
#
Ohai.plugin do
- provides "kernel"
+ provides "kernel/os", "kernel/machine", "kernel/modules"
+ depends "kernel/name"
collect_data do
kernel[:os] = kernel[:name]
diff --git a/lib/ohai/plugins/kernel.rb b/lib/ohai/plugins/kernel.rb
index bfadcda0..a3f508f4 100644
--- a/lib/ohai/plugins/kernel.rb
+++ b/lib/ohai/plugins/kernel.rb
@@ -18,8 +18,9 @@
Ohai.plugin do
provides "kernel"
+ provides "kernel/name", "kernel/release", "kernel/version", "kernel/machine", "kernel/modules"
- depends 'ruby'
+ depends "languages/ruby"
collect_data do
kernel Mash.new
diff --git a/lib/ohai/runner.rb b/lib/ohai/runner.rb
new file mode 100644
index 00000000..84d53e48
--- /dev/null
+++ b/lib/ohai/runner.rb
@@ -0,0 +1,93 @@
+#
+# Author:: Claire McQuin (<claire@opscode.com>)
+# Copyright:: Copyright (c) 2013 Opscode, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you
+# may not use this file except in compliance with the License. You may
+# obtain a copy of the license at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either expressed or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License
+#
+
+require 'ohai/dsl/plugin'
+
+module Ohai
+ class NoAttributeError < Exception
+ end
+
+ class DependencyCycleError < Exception
+ end
+
+ class Runner
+ # safe_run: set to true if this runner will run plugins in
+ # safe-mode. default false.
+ def initialize(controller, safe_run = false)
+ @attributes = controller.attributes
+ @safe_run = safe_run
+ end
+
+ # runs this plugin and any un-run dependencies. if force is set to
+ # true, then this plugin and its dependencies will be run even if
+ # they have been run before.
+ def run_plugin(plugin, force = false)
+ visited = [plugin]
+ while !visited.empty?
+ p = visited.pop
+ unless force
+ next if p.has_run?
+ end
+
+ if visited.include?(p)
+ raise DependencyCycleError, "Dependency cycle detected. Please examine the following plugin files: #{cycle_sources(visited, p).join(", ")}"
+ end
+
+ dependency_providers = fetch_providers(p.dependencies)
+ dependency_providers.delete_if { |provider| (!force && provider.has_run?) || provider.eql?(p) }
+
+ if dependency_providers.empty?
+ @safe_run ? p.safe_run : p.run
+ else
+ visited << p << dependency_providers
+ visited.flatten!
+ end
+ end
+ end
+
+ # returns a list of plugins which provide the given attributes
+ def fetch_providers(attributes)
+ providers = []
+ attributes.each do |attribute|
+ attrs = @attributes
+ parts = attribute.split('/')
+ parts.each do |part|
+ next if part == Ohai::OS.collect_os
+ raise NoAttributeError, "Cannot find plugin providing attribute \'#{attribute}\'" unless attrs[part]
+ attrs = attrs[part]
+ end
+ providers << attrs[:providers]
+ providers.flatten!
+ end
+ providers.uniq!
+ providers
+ end
+
+ # given a list of plugins and the first plugin in the cycle,
+ # returns the list of plugin source files responsible for the
+ # cycle. does not include plugins that aren't a part of the cycle
+ def cycle_sources(plugins, cycle_start)
+ plugins.drop_while { |plugin| !plugin.eql?(cycle_start) }
+ sources = []
+ plugins.each { |plugin| sources << plugin.source }
+ sources
+ end
+
+ end
+end
diff --git a/lib/ohai/system.rb b/lib/ohai/system.rb
index bdc171d7..4a255eef 100644
--- a/lib/ohai/system.rb
+++ b/lib/ohai/system.rb
@@ -20,6 +20,7 @@ require 'ohai/loader'
require 'ohai/log'
require 'ohai/mash'
require 'ohai/os'
+require 'ohai/runner'
require 'ohai/dsl/plugin'
require 'ohai/mixin/from_file'
require 'ohai/mixin/command'
@@ -37,7 +38,7 @@ module Ohai
def initialize
@data = Mash.new
- @attributes = Hash.new
+ @attributes = Mash.new
@hints = Hash.new
@v6_dependency_solver = Hash.new
@plugin_path = ""
@@ -58,18 +59,29 @@ module Ohai
file_regex = Regexp.new("#{File.expand_path(path)}#{File::SEPARATOR}(.+).rb$")
md = file_regex.match(file)
if md
- plugin_path = md[0]
- unless @v6_dependency_solver.has_key?(plugin_path)
- plugin = loader.load_plugin(plugin_path)
- @v6_dependency_solver[plugin_path] = plugin unless plugin.nil?
+ unless @v6_dependency_solver.has_key?(file)
+ plugin = loader.load_plugin(file)
+ @v6_dependency_solver[file] = plugin unless plugin.nil?
else
- Ohai::Log.debug("Already loaded plugin at #{plugin_path}")
+ Ohai::Log.debug("Already loaded plugin at #{file}")
end
end
end
end
end
+ def run_plugins(safe = false, force = false)
+ runner = Ohai::Runner.new(self, safe)
+ plugins = collect_providers(@attributes)
+ begin
+ plugins.each { |plugin| runner.run_plugin(plugin, force) }
+ rescue DependencyCycleError, NoAttributeError => e
+ Ohai::Log.error("Encountered error while running plugins: #{e.inspect}")
+ raise
+ end
+ nil
+ end
+
def all_plugins
require_plugin('os')
@@ -97,19 +109,19 @@ module Ohai
end
def collect_providers(providers)
- refreshments = []
+ plugins = []
if providers.is_a?(Mash)
providers.keys.each do |provider|
- if provider.eql?("_providers")
- refreshments << providers[provider]
+ if provider.eql?("providers")
+ plugins << providers[provider]
else
- refreshments << collect_providers(providers[provider])
+ plugins << collect_providers(providers[provider])
end
end
else
- refreshments << providers
+ plugins << providers
end
- refreshments.flatten.uniq
+ plugins.flatten.uniq
end
def refresh_plugins(path = '/')