Class: Bixby::App
- Inherits:
-
Object
- Object
- Bixby::App
- Includes:
- CLI, Log
- Defined in:
- lib/bixby-agent/app.rb,
lib/bixby-agent/app/cli.rb
Defined Under Namespace
Modules: CLI
Instance Method Summary collapse
-
#close_fds ⇒ Object
Copied from daemons gem.
-
#ensure_state_dir(daemon_dir) ⇒ Object
Ensure that the var dir exists and is writable.
-
#fix_ownership ⇒ Object
If running as root, fix ownership of var and etc dirs.
-
#load_agent ⇒ Object
Load Agent.
-
#run! ⇒ Object
Run the agent app!.
-
#start_websocket_client ⇒ Object
Open the WebSocket channel with the Manager.
- #trap_signals ⇒ Object
-
#validate_argv ⇒ Object
Validate ARGV.
Methods included from CLI
Instance Method Details
#close_fds ⇒ Object
Copied from daemons gem. We hit a bug where closing FDs failed, so close them all cleanly before daemonizing.
197 198 199 200 201 202 203 204 205 |
# File 'lib/bixby-agent/app.rb', line 197 def close_fds # don't close stdin/out/err (0/1/2) 3.upto(8192).each do |i| begin IO.for_fd(i).close rescue Exception end end end |
#ensure_state_dir(daemon_dir) ⇒ Object
Ensure that the var dir exists and is writable
180 181 182 183 184 185 186 187 188 189 190 191 192 193 |
# File 'lib/bixby-agent/app.rb', line 180 def ensure_state_dir(daemon_dir) if not File.directory? daemon_dir then begin Dir.mkdir(daemon_dir) rescue Exception => ex $stderr.puts "Failed to create state dir: #{daemon_dir}; message:\n" + ex. exit 1 end end if not File.writable? daemon_dir then $stderr.puts "State dir is not writable: #{daemon_dir}" exit 1 end end |
#fix_ownership ⇒ Object
If running as root, fix ownership of var and etc dirs
147 148 149 150 151 152 153 154 155 156 |
# File 'lib/bixby-agent/app.rb', line 147 def fix_ownership return if Process.uid != 0 begin uid = Etc.getpwnam("bixby").uid gid = Etc.getgrnam("bixby").gid # user/group exists, chown File.chown(uid, gid, Bixby.path("var"), Bixby.path("etc")) rescue ArgumentError end end |
#load_agent ⇒ Object
Load Agent
Load the agent from $BIXBY_HOME. If no existing configuration was found, try to register with the server if we have the correct parameters.
19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
# File 'lib/bixby-agent/app.rb', line 19 def load_agent begin agent = Agent.create(@config[:directory]) rescue Exception => ex if ex. =~ /manager URI/ then # if unable to load from config and no/bad uri passed, bail! $stderr.puts "ERROR: a valid manager URI is required on first run" $stderr.puts $stderr.puts @opt_parser.help() exit 1 end raise ex end # TODO disable mac detection for now; it doesn't work in certain cases # e.g., when you stop/start an instance on EC2 a new mac is issued # # if not agent.new? and agent.mac_changed? then # # loaded from config and mac has changed # agent = Agent.create(opts, false) # end if agent.new? then if !@config[:register] then # --register not passed, bail out if File.exists? agent.config_file then $stderr.puts "Unable to load agent config from #{agent.config_file}; pass --register to reinitialize" else $stderr.puts "Unable to load agent from BIXBY_HOME=#{ENV['BIXBY_HOME']}; pass --register to initialize" end exit 1 end # validate uri uri = @argv.shift || @config[:register] begin if uri.nil? or URI.parse(uri).nil? or URI.join(uri, "/api").nil? then raise ConfigException, "Missing manager URI", caller end rescue URI::Error => ex raise ConfigException, "Bad manager URI: '#{uri}'" end # register $stdout.puts "Going to register with manager: #{uri}" if (ret = agent.register_agent(uri, @config[:token], @config[:tags])).fail? then $stderr.puts "error: failed to register with manager!" $stderr.puts "reason:" if ret. =~ /900 seconds old/ then Help::SystemTime.print() else $stderr.puts " #{ret.}" end exit 1 end agent.save_config() ARGV.clear # make sure it's empty so daemon starts properly $stdout.puts "Registration successful; launching bixby-agent into background" end agent end |
#run! ⇒ Object
Run the agent app!
This is the main method. Will boot and configure the agent, connect to the server and start the daemon.
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/bixby-agent/app.rb', line 87 def run! # load agent from config or cli opts agent = load_agent() fix_ownership() # debug mode, stay in front if @config[:debug] then Logging::Logger.root.add_appenders("stdout") return start_websocket_client() end # start daemon validate_argv() daemon_dir = Bixby.path("var") ensure_state_dir(daemon_dir) close_fds() daemon_opts = { :dir => daemon_dir, :dir_mode => :normal, :log_output => true, :stop_proc => lambda { logger.info "Agent shutdown on service stop command" } } Daemons.run_proc("bixby-agent", daemon_opts) do Logging.logger.root.clear_appenders start_websocket_client() end end |
#start_websocket_client ⇒ Object
Open the WebSocket channel with the Manager
NOTE: this call will not return!
121 122 123 124 125 126 127 128 |
# File 'lib/bixby-agent/app.rb', line 121 def start_websocket_client # make sure log level is still set correctly here Bixby::Log.setup_logger(:level => Logging.appenders["file"].level) logger.info "Started Bixby Agent #{Bixby::Agent::VERSION}" @client = Bixby::WebSocket::Client.new(Bixby.agent.manager_ws_uri, AgentHandler) trap_signals() @client.start end |
#trap_signals ⇒ Object
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/bixby-agent/app.rb', line 130 def trap_signals Bixby::Signal.trap(%w{INT QUIT TERM}) do |sig| @client.stop() if sig == "INT" then puts # to get a blank line after the ^C in the term reason = " (^C)" else reason = "" end logger.warn "caught #{sig}#{reason} signal; exiting" end Bixby::ThreadDump.trap! end |
#validate_argv ⇒ Object
Validate ARGV
If empty, default to “start”, otherwise make sure we have a valid option for daemons.
164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/bixby-agent/app.rb', line 164 def validate_argv if ARGV.empty? then ARGV << "start" else if not %w{start stop restart zap status}.include? ARGV.first then $stderr.puts "ERROR: invalid command '#{ARGV.first}'" $stderr.puts $stderr.puts @opt_parser.help() exit 1 end end end |