lib/onering/plugins/reporter.rb in onering-client-0.1.2 vs lib/onering/plugins/reporter.rb in onering-client-0.1.3

- old
+ new

@@ -21,10 +21,13 @@ DEFAULT_FACTER_PATH = [ '/etc/facter' ] + DEFAULT_CACHE_FILE='/var/tmp/.onering-report-cache.json' + DEFAULT_CACHE_MAXAGE=600 + class<<self include Onering::Util attr_reader :facter_path @@ -141,32 +144,99 @@ def report() @id = (@options[:id] || Onering::Util.fact('hardwareid', nil)) if not @id.nil? - Timeout.timeout((@options[:timeout] || 60).to_i) do - hostname = (Facter.value('fqdn') rescue %x{hostname -f}.strip.chomp) + if @options[:nocache] + return _generated_report() + else + rv = _cached_report() + return _generated_report() if rv.nil? or rv.empty? + return rv + end + else + Onering::Logger.fatal!("Cannot generate report without a hardware ID", "Onering::Reporter") + end - @_report = { - :id => @id, - :name => hostname, - :aliases => @options[:aliases], - :tags => @options[:tags], - :status => (@options[:status] || 'online'), - :inventory => true, - :properties => {} - } + return {} + end - # loads plugins and populates @_report - load_plugins - return @_report.stringify_keys() + def _generated_report() + Timeout.timeout((@options[:timeout] || 60).to_i) do + hostname = (Facter.value('fqdn') rescue %x{hostname -f}.strip.chomp) + + @_report = { + :id => @id, + :name => hostname, + :aliases => @options[:aliases], + :tags => @options[:tags], + :status => (@options[:status] || 'online'), + :inventory => true, + :properties => {} + } + + # loads plugins and populates @_report + load_plugins + + return @_report.stringify_keys() + end + + return {} + end + + def _cached_report() + cachefile = (@options[:cachefile] || DEFAULT_CACHE_FILE) + + catch(:retry) do + if File.readable?(cachefile) + Onering::Logger.debug("Loading cache file at #{cachefile}", "Onering::Reporter") + cache = File.read(cachefile) + cache = (MultiJson.load(cache) rescue {}) + + if _cache_expired?(cache, @options[:maxage]) + Onering::Logger.debug("Cache expired, regenerating...", "Onering::Reporter") + throw :retry if _update_cache_file(cachefile) + end + + # remove cached_at key + Onering::Logger.debug("Using cached data (#{Time.now.to_i - Time.parse(cache.get('cached_at')).to_i} seconds old)", "Onering::Reporter") + cache.delete('cached_at') + return cache + else + Onering::Logger.debug("Report cache file could not be read at #{cachefile}", "Onering::Reporter") + throw :retry if _update_cache_file(cachefile) end - else - Onering::Logger.fatal!("Cannot generate report without a hardware ID", "Onering::Reporter") end - {} + return {} + end + + + def _update_cache_file(cachefile=DEFAULT_CACHE_FILE) + begin + File.open(cachefile, 'w+') do |file| + Onering::Logger.debug("Regenerating cache file at #{cachefile}", "Onering::Reporter") + report = _generated_report() + report['cached_at'] = Time.now.strftime('%Y-%m-%dT%H:%M:%S%z') + json = MultiJson.dump(report, :pretty => true) + file.puts(json) + end + + return true + rescue Exception => e + Onering::Logger.warn("Error while writing cache file #{cachefile}: #{e.class.name} - #{e.message}", "Onering::Reporter") + return false + end + end + + + def _cache_expired?(cache, age=DEFAULT_CACHE_MAXAGE) + if cache.is_a?(Hash) + return (Time.parse(cache.get('cached_at')) < (Time.now - age) rescue true) + else + return true + end end end end end