# -*- encoding: utf-8 -*- module WatchTower module CLI module Start def self.included(base) base.send :include, InstanceMethods end module InstanceMethods def self.included(base) base.class_eval <<-END, __FILE__, __LINE__ + 1 # Mappings (aliases) map "-s" => :start # Start watchtower desc "start", "Start the Watch Tower" method_option :bootloader, type: :boolean, required: false, aliases: "-b", default: false, desc: "Is it invoked from the bootloader?" method_option :foreground, type: :boolean, required: false, aliases: "-f", default: false, desc: "Do not run in the background." method_option :host, type: :string, required: false, aliases: "-h", default: 'localhost', desc: "Set the server's host" method_option :port, type: :numeric, required: false, aliases: "-p", default: 9282, desc: "Set the server's port." method_option :debug, type: :boolean, required: false, aliases: "-d", default: false, desc: "Run in debug mode." def start # Set the logger to debug mode if necessary LOG.level = Logger::DEBUG if options[:debug] begin if Config[:enabled] && (!options[:bootloader] || (options[:bootloader] && Config[:launch_on_boot])) LOG.info "#{__FILE__}:#{__LINE__}: Starting WatchTower." start! LOG.info "#{__FILE__}:#{__LINE__}: WatchTower has finished." else abort "You need to edit the config file located at \#{Config.config_file}." end rescue ConfigNotReadableError => e LOG.fatal "#{__FILE__}:#{__LINE__}: The config file is not readable." STDERR.puts "The config file is not readable, please make sure \#{Config.config_file} exists and you have the necessary permissions to read it." exit(1) rescue ConfigNotValidError => e LOG.fatal "#{__FILE__}:#{__LINE__}: The config file is not valid: \#{e.message}." STDERR.puts "The config file \#{Config.config_file} is not valid: \#{e.message}." exit(1) end end protected def start! if options[:foreground] LOG.debug "#{__FILE__}:#{__LINE__}: Running WatchTower in foreground." # Start WatchTower start_watch_tower else LOG.debug "#{__FILE__}:#{__LINE__}: Running WatchTower in the background." pid = fork do begin # Try to replace ruby with WatchTower in the command line (for ps) $0 = 'watchtower' unless $0 == 'watchtower' # Tell ruby that we are a daemon Process.daemon # Start WatchTower start_watch_tower rescue => e LOG.fatal "#{__FILE__}:#{__LINE__ - 2}: The process raised an exception \#{e.message}" LOG.fatal "#{__FILE__}:#{__LINE__ - 3}: ==== Backtrace ====" e.backtrace.each do |trace| LOG.fatal "#{__FILE__}:#{__LINE__ - 5}: \#{trace}" end end end end end # Start watch tower # This method just start the watch tower it doesn't know # or care if we are in a forked process or not, all it cares about # is starting the database server before starting the eye # # see #start_server # see #start_eye def start_watch_tower # Start the server start_server # Wait until the database starts until Server::Database.is_connected? do sleep(1) end # Wait until the database has migrated until Server::Database.is_migrated? do sleep(1) end # Start the eye now. start_eye end # Start the eye # This method just start the watch tower it doesn't know # or care if we are in a forked process or not def start_eye LOG.debug "#{__FILE__}:#{__LINE__}: Starting the eye." Eye.start!(watch_tower_options) end # Start the web server # This method just start the watch tower it doesn't know # or care if we are in a forked process or not def start_server LOG.debug "#{__FILE__}:#{__LINE__}: Starting the web server." Server.start!(watch_tower_options) end # Return Watch Tower options # same as options but modified to correspond to WatchTower options # instead of CLI options # # @return [Hash] options def watch_tower_options return @watch_tower_options if @watch_tower_options @watch_tower_options = options.dup @watch_tower_options.delete(:bootloader) # Log the options as a Debug LOG.debug "#{__FILE__}:#{__LINE__}: Options are \#{@watch_tower_options.inspect}." # Return the options @watch_tower_options end END end end end end end