diff options
author | Claire McQuin <claire@opscode.com> | 2013-09-03 14:24:12 -0700 |
---|---|---|
committer | Claire McQuin <claire@opscode.com> | 2013-09-03 14:53:08 -0700 |
commit | bf6f552c3c70ef836151ae832efde121c3222944 (patch) | |
tree | e4f8912b80605c52192d30745d060ccb650d29d4 /lib | |
parent | ff149f9a1ea45f63bf785bd3ccc6d8e9e7d87739 (diff) | |
download | ohai-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.rb | 2 | ||||
-rw-r--r-- | lib/ohai/plugins/darwin/kernel.rb | 3 | ||||
-rw-r--r-- | lib/ohai/plugins/kernel.rb | 3 | ||||
-rw-r--r-- | lib/ohai/runner.rb | 93 | ||||
-rw-r--r-- | lib/ohai/system.rb | 36 |
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 = '/') |