lib/bmc-daemon-lib/conf.rb in bmc-daemon-lib-0.12.2 vs lib/bmc-daemon-lib/conf.rb in bmc-daemon-lib-0.13.2

- old
+ new

@@ -12,103 +12,71 @@ class Conf extend Chamber PIDFILE_DIR = "/tmp/" + # Set up encodings + Encoding.default_internal = "utf-8" + Encoding.default_external = "utf-8" + + # Some global init + @app_started = Time.now + @app_name = "" + @app_env = "production" + @app_host = `hostname`.to_s.chomp.split(".").first + + # By default, Newrelic is disabled + ENV["NEWRELIC_AGENT_ENABLED"] = "false" + class << self - attr_accessor :app_env attr_reader :app_root - attr_reader :app_libs + attr_reader :app_started attr_reader :app_name + attr_reader :app_env + attr_reader :app_host attr_reader :app_ver - attr_reader :app_started attr_reader :app_spec - attr_reader :files - attr_reader :host - end + attr_reader :app_config - def self.init app_root - # Permanent flags - @initialized = true - @app_started = Time.now + def app_env= value + @app_env = value + ENV["RACK_ENV"] = value.to_s + end - # Default values - @files ||= [] - @app_name ||= "app_name" - @app_env ||= "production" - @host ||= `hostname`.to_s.chomp.split(".").first + def app_config= path + @app_config= path + end - # Store and clean app_root - @app_root = File.expand_path(app_root) - gemspec_path = "#{@app_root}/*.gemspec" + def cmd_config= path + @app_config= path + end - # Try to find any gemspec file - matches = Dir[gemspec_path] - fail ConfigGemspecMissing, "gemspec file not found: #{gemspec_path}" if matches.size < 1 - fail ConfigGemspecNotUnique, "gemspec file not found: #{gemspec_path}" if matches.size > 1 + # def self.init app_root = nil + def app_root= path + self.init_from path + end - # Load Gemspec (just the only match) - @spec = Gem::Specification::load(matches.first) - fail ConfigGemspecInvalid, "gemspec not readable: #{gemspec_path}" unless @spec + def init_from path + # Store it + @app_root = ::File.expand_path(path) + return unless @app_root - # Extract useful information from gemspec - @app_name = @spec.name.to_s - @app_ver = @spec.version.to_s - fail ConfigMissingParameter, "gemspec: missing name" unless @app_name - fail ConfigMissingParameter, "gemspec: missing version" unless @app_ver + # Read the gemspec + gemspec = init_from_gemspec - # Now we know app_name, initalize app_libs - @app_libs = File.expand_path("lib/#{@app_name}/", @app_root) + #return gemspec + return @app_root + end - # By default, Newrelic is disabled - ENV["NEWRELIC_AGENT_ENABLED"] = "false" - - # Add other config files - add_config generate_config_defaults - add_config generate_config_etc - - # Return something - return @app_name + def dump + to_hash.to_yaml(indent: 4, useheader: true, useversion: false ) + end + end - def self.prepare args = {} - ensure_init - - # Add extra config file and load them all - add_config args[:config] - reload! - - # Set Rack env - ENV["RACK_ENV"] = @app_env.to_s - - # Set up encodings - Encoding.default_internal = "utf-8" - Encoding.default_external = "utf-8" - - # Try to access any key to force parsing of the files - self[:test35547647654856865436346453754746588586799078079876543245678654324567865432] - - rescue Psych::SyntaxError => e - fail ConfigParseError, e.message - rescue StandardError => e - fail ConfigOtherError, "#{e.message} \n #{e.backtrace.to_yaml}" - end - - # Reload files - def self.reload! - ensure_init - load_files - end - - def self.dump - ensure_init - to_hash.to_yaml(indent: 4, useheader: true, useversion: false ) - end - # Direct access to any depth def self.at *path - ensure_init path.reduce(Conf) { |m, key| m && m[key.to_s] } end def self.logfile pipe # Build logfile from Conf @@ -138,21 +106,17 @@ # Feature testers def self.gem_installed? gemname Gem::Specification.collect(&:name).include? gemname end - - def self.feature_newrelic? - ensure_init return false unless gem_installed?('newrelic_rpm') return false if self.at(:newrelic, :enabled) == false return false if self.at(:newrelic, :disabled) == true return self.at(:newrelic, :license) || false end def self.feature_rollbar? - ensure_init return false unless gem_installed?('rollbar') return false if self.at(:rollbar, :enabled) == false return false if self.at(:rollbar, :disabled) == true return self.at(:rollbar, :token) || false end @@ -166,40 +130,50 @@ end return false end # Generators + def self.app_libs + check_presence_of @app_name, @app_root + + ::File.expand_path("lib/#{@app_name}/", @app_root) + end + def self.generate_user_agent - ensure_init - "#{@app_name}/#{@app_ver}" if @app_name && @app_ver + check_presence_of @app_name, @app_ver + + "#{@app_name}/#{@app_ver}" end - def self.generate_config_defaults - ensure_init - "#{@app_root}/defaults.yml" if @app_root - end - def self.generate_config_etc - ensure_init - "/etc/#{@app_name}.yml" if @app_name - end + def self.generate_process_name - ensure_init + check_presence_of @app_name, @app_env + parts = [@app_name, @app_env] parts << self[:port] if self[:port] parts.join('-') end + + def self.generate_config_defaults + check_presence_of @app_root + "#{@app_root}/defaults.yml" + end + + def self.generate_config_etc + check_presence_of @app_name + "/etc/#{@app_name}.yml" + end + def self.generate_pidfile - ensure_init - process_name = self.generate_process_name - File.expand_path "#{process_name}.pid", PIDFILE_DIR + ::File.expand_path "#{self.generate_process_name}.pid", PIDFILE_DIR end + def self.generate_config_message - ensure_init - config_defaults = self.generate_config_defaults - config_etc = self.generate(:config_etc) - "A default configuration is available (#{config_defaults}) and can be copied to the default location (#{config_etc}): \n sudo cp #{config_defaults} #{config_etc}" + return unless self.generate_config_defaults && self.generate_config_etc + "A default configuration is available (#{self.generate_config_defaults}) and can be copied to the default location (#{self.generate_config_etc}): \n sudo cp #{self.generate_config_defaults} #{self.generate_config_etc}" end + # Plugins def self.prepare_newrelic # Disable if no config present return unless self.feature?(:newrelic) # Ok, let's start @@ -215,21 +189,10 @@ # Set env variables ENV["NEW_RELIC_AGENT_ENABLED"] = "true" ENV["NEW_RELIC_LOG"] = logfile_path(:newrelic) ENV["NEW_RELIC_LICENSE_KEY"] = conf[:license].to_s ENV["NEW_RELIC_APP_NAME"] = conf[:app_name].to_s - - # logger_newrelic = Logger.new('/tmp/newrelic.log') - # logger_newrelic.debug Time.now() - # Start the agent - # NewRelic::Agent.manual_start({ - # agent_enabled: true, - # log: logger_newrelic, - # env: @app_env, - # license_key: conf[:license].to_s, - # app_name: conf[:app_name].to_s, - # }) end def self.prepare_rollbar # Disable if no config present unless self.feature?(:rollbar) @@ -252,11 +215,11 @@ config.logger = LoggerPool.instance.get(:rollbar) config.use_async = true end # Notify startup - Rollbar.info("[#{@app_ver}] #{@host}") + Rollbar.info("[#{@app_ver}] #{@app_host}") end def self.log origin, message printf( "%s %-14s %s \n", @@ -266,41 +229,97 @@ ) end protected + def self.init_from_gemspec + # Check conditions + check_presence_of @app_root + + # puts "Conf.init_from_gemspec" + gemspec_path = "#{@app_root}/*.gemspec" + + # Try to find any gemspec file + matches = Dir[gemspec_path] + fail ConfigGemspecMissing, "gemspec file not found: #{gemspec_path}" if matches.size < 1 + fail ConfigGemspecNotUnique, "gemspec file not found: #{gemspec_path}" if matches.size > 1 + + # Load Gemspec (just the only match) + @spec = Gem::Specification::load(matches.first) + fail ConfigGemspecInvalid, "gemspec not readable: #{gemspec_path}" unless @spec + + # Extract useful information from gemspec + @app_name = @spec.name.to_s + @app_ver = @spec.version.to_s + fail ConfigMissingParameter, "gemspec: missing name" unless @app_name + fail ConfigMissingParameter, "gemspec: missing version" unless @app_ver + + return @spec + end + def self.newrelic_init_app_name conf # Ignore if already set - return if conf[:app_name] + return if @app_name + # Check conditions + check_presence_of @app_env + # Stack all those parts stack = [] stack << (conf[:prefix] || @app_name) stack << conf[:platform] if conf[:platform] stack << @app_env text = stack.join('-') # Return a composite appname - conf[:app_name] = "#{text}; #{text}-#{@host}" + conf[:app_name] = "#{text}; #{text}-#{@app_host}" end - def self.load_files - load files: @files, namespaces: { environment: @app_env } + def self.reload + files=[] + + # Load defaults + add_config(files, self.generate_config_defaults) + + # Load etc config + add_config(files, self.generate_config_etc) + + # Load app config + add_config(files, @app_config) + + # Reload config + # puts "Conf.reload: loading files: #{files.inspect}" + log :conf, "reloading from files: #{files.inspect}" + load files: files, namespaces: { environment: @app_env } + + # Try to access any key to force parsing of the files + self[:test35547647654856865436346453754746588586799078079876543245678654324567865432] + + rescue Psych::SyntaxError => e + fail ConfigParseError, e.message + rescue StandardError => e + fail ConfigOtherError, "#{e.message} \n #{e.backtrace.to_yaml}" + + else + return to_hash end - def self.add_config path - # Skip if path is not readable - return unless path && File.readable?(path) + def self.add_config files, path + # Should be not empty/nil + return unless path + # Should be readable + return unless File.readable?(path) + # Check if Chamber's behaviour may cause problems with hyphens basename = File.basename(path) - if File.basename(path).include?'-' + if basename.include?'-' log :conf, "WARNING: files with dashes may cause unexpected behaviour with Chamber (#{basename})" end - # Store the files - @files << File.expand_path(path) + # Add it + files << File.expand_path(path) end def self.logfile_path pipe # Access configuration path = self.at :logs, :path @@ -318,12 +337,20 @@ File.expand_path specific.to_s, path.to_s end private - def self.ensure_init - unless @initialized - fail ConfigInitiRequired, "ensure_init: Conf.init(app_root) should be invoked beforehand" + # Check every argument for value presence + def self.check_presence_of *args + # puts "check_presence_of #{args.inspect}" + args.each do |arg| + # OK if it's not empty + # puts "- [#{arg}]" + next unless arg.to_s.empty? + + # Otherise, we just exit + log :conf, "FAILED: object Conf has not been initialized correctly yet" + exit 200 end end end end