3 # A base class for fact providers, to make a new fully functional fact provider
4 # inherit from this and simply provide a self.get_facts method that returns a
16 # Registers new fact sources into the plugin manager
17 def self.inherited(klass)
18 PluginManager << {:type => "facts_plugin", :class => klass.to_s}
21 # Returns the value of a single fact
22 def get_fact(fact=nil)
23 config = Config.instance
25 cache_time = config.fact_cache_time || 300
29 if (Time.now.to_i - @last_facts_load > cache_time.to_i ) || force_reload?
30 Log.debug("Resetting facter cache, now: #{Time.now.to_i} last-known-good: #{@last_facts_load}")
32 tfacts = load_facts_from_source
34 # Force reset to last known good state on empty facts
35 raise "Got empty facts" if tfacts.empty?
39 tfacts.each_pair do |key,value|
40 @facts[key.to_s] = value.to_s
43 @last_good_facts = @facts.clone
44 @last_facts_load = Time.now.to_i
46 Log.debug("Using cached facts now: #{Time.now.to_i} last-known-good: #{@last_facts_load}")
49 Log.error("Failed to load facts: #{e.class}: #{e}")
51 # Avoid loops where failing fact loads cause huge CPU
52 # loops, this way it only retries once every cache_time
54 @last_facts_load = Time.now.to_i
56 # Revert to last known good state
57 @facts = @last_good_facts.clone
62 # If you do not supply a specific fact all facts will be returned
66 @facts.include?(fact) ? @facts[fact] : nil
75 # Returns true if we know about a specific fact, false otherwise
77 get_fact(nil).include?(fact)
80 # Plugins can override this to provide forced fact invalidation