X-Git-Url: https://review.fuel-infra.org/gitweb?a=blobdiff_plain;f=lib%2Fmcollective%2Ffacts%2Fbase.rb;fp=lib%2Fmcollective%2Ffacts%2Fbase.rb;h=c5cb4bba565bc5b3079e12de303e7569449e6bac;hb=b87d2f4e68281062df1913440ca5753ae63314a9;hp=0000000000000000000000000000000000000000;hpb=ab0ea530b8ac956091f17b104ab2311336cfc250;p=packages%2Fprecise%2Fmcollective.git diff --git a/lib/mcollective/facts/base.rb b/lib/mcollective/facts/base.rb new file mode 100644 index 0000000..c5cb4bb --- /dev/null +++ b/lib/mcollective/facts/base.rb @@ -0,0 +1,86 @@ +module MCollective + module Facts + # A base class for fact providers, to make a new fully functional fact provider + # inherit from this and simply provide a self.get_facts method that returns a + # hash like: + # + # {"foo" => "bar", + # "bar" => "baz"} + class Base + def initialize + @facts = {} + @last_good_facts = {} + @last_facts_load = 0 + end + + # Registers new fact sources into the plugin manager + def self.inherited(klass) + PluginManager << {:type => "facts_plugin", :class => klass.to_s} + end + + # Returns the value of a single fact + def get_fact(fact=nil) + config = Config.instance + + cache_time = config.fact_cache_time || 300 + + Thread.exclusive do + begin + if (Time.now.to_i - @last_facts_load > cache_time.to_i ) || force_reload? + Log.debug("Resetting facter cache, now: #{Time.now.to_i} last-known-good: #{@last_facts_load}") + + tfacts = load_facts_from_source + + # Force reset to last known good state on empty facts + raise "Got empty facts" if tfacts.empty? + + @facts.clear + + tfacts.each_pair do |key,value| + @facts[key.to_s] = value.to_s + end + + @last_good_facts = @facts.clone + @last_facts_load = Time.now.to_i + else + Log.debug("Using cached facts now: #{Time.now.to_i} last-known-good: #{@last_facts_load}") + end + rescue Exception => e + Log.error("Failed to load facts: #{e.class}: #{e}") + + # Avoid loops where failing fact loads cause huge CPU + # loops, this way it only retries once every cache_time + # seconds + @last_facts_load = Time.now.to_i + + # Revert to last known good state + @facts = @last_good_facts.clone + end + end + + + # If you do not supply a specific fact all facts will be returned + if fact.nil? + return @facts + else + @facts.include?(fact) ? @facts[fact] : nil + end + end + + # Returns all facts + def get_facts + get_fact(nil) + end + + # Returns true if we know about a specific fact, false otherwise + def has_fact?(fact) + get_fact(nil).include?(fact) + end + + # Plugins can override this to provide forced fact invalidation + def force_reload? + false + end + end + end +end