def __start_neubot_agent(): ''' Fork a new process and run neubot agent ''' # Fork a new process pid = os.fork() if pid > 0: syslog.syslog(syslog.LOG_INFO, 'Neubot agent PID: %d' % pid) return pid # # The child code is surrounded by this giant try..except # because we don't want the child process to eventually # return to the caller. # try: syslog.openlog('neubot', syslog.LOG_PID, syslog.LOG_DAEMON) # Add neubot directory to python search path if not os.access(VERSIONDIR, os.R_OK|os.X_OK): raise RuntimeError('Cannot access: %s' % VERSIONDIR) if not VERSIONDIR in sys.path: syslog.syslog(syslog.LOG_ERR, 'Prepending "%s" to Python search path' % VERSIONDIR) sys.path.insert(0, VERSIONDIR) # Import the required modules from neubot.log import LOG from neubot.net.poller import POLLER from neubot import agent # # Redirect logger to syslog now, so early errors in # agent.py:main() are logged. # LOG.redirect() # # Close all unneeded file descriptors, but save stdio, # which has just been redirected. # for tmpdesc in range(3, 64): try: os.close(tmpdesc) except OSError: pass except: pass # Handle SIGTERM gracefully sigterm_handler = lambda signo, frame: POLLER.break_loop() signal.signal(signal.SIGTERM, sigterm_handler) # # Here we're running as root but this is OK because # neubot/agent.py is going to drop the privileges to # the unprivileged user `_neubot`. # agent.main(['neubot/agent.py', '-D agent.daemonize=OFF', '-D agent.use_syslog=ON']) # # We must employ __exit() instead of sys.exit() because # the latter is catched below by our catch-all clauses and # the child process will start running the parent code. # OTOH __exit() exits immediately. # except: try: why = asyncore.compact_traceback() syslog.syslog(syslog.LOG_ERR, 'Unhandled exception in the Neubot agent: %s' % str(why)) except: pass __exit(1) else: __exit(0)
def main(argv): slowpath = False webgui = False start = False status = False stop = False if sys.version_info[0] > 2 or sys.version_info[1] < 5: sys.stderr.write("fatal: wrong Python version\n") sys.stderr.write("please run neubot using Python >= 2.5 and < 3.0\n") sys.exit(1) if os.environ.get("NEUBOT_DEBUG", ""): from neubot import utils if utils.intify(os.environ["NEUBOT_DEBUG"]): sys.stderr.write("Running in debug mode\n") from neubot.debug import PROFILER sys.setprofile(PROFILER.notify_event) if os.environ.get("NEUBOT_MEMLEAK", ""): from neubot import utils if utils.intify(os.environ["NEUBOT_MEMLEAK"]): sys.stderr.write("Running in leak-detection mode\n") import gc gc.set_debug(gc.DEBUG_LEAK) # Hook for Neubot for MacOSX if os.name == 'posix' and sys.platform == 'darwin': from neubot import main_macos main_macos.main(argv) return # Quick argv classification if len(argv) == 1: start = True webgui = True elif len(argv) == 2: command = argv[1] if command == "--help": sys.stdout.write(USAGE) sys.exit(0) elif command == "-V": sys.stdout.write(VERSION + "\n") sys.exit(0) elif command == "start": start = True elif command == "status": status = True elif command == "stop": stop = True else: slowpath = True else: slowpath = True # Slow / quick startup if slowpath: from neubot.main import module module.run(argv) else: running = False # Running? if start or status or stop: try: import httplib connection = httplib.HTTPConnection("127.0.0.1", "9774") connection.request("GET", "/api/version") response = connection.getresponse() if response.status == 200: running = True response.read() connection.close() except (SystemExit, KeyboardInterrupt): raise except: pass if status: if not running: sys.stdout.write("Not running\n") else: sys.stdout.write("Running\n") sys.exit(0) if running and start: sys.stdout.write("Already running\n") if not running and stop: sys.stdout.write("Not running\n") # Stop if running and stop: try: connection = httplib.HTTPConnection("127.0.0.1", "9774") connection.request("POST", "/api/exit") # New /api/exit does not send any response #response = connection.getresponse() connection.close() except (SystemExit, KeyboardInterrupt): raise except: logging.error('Exception', exc_info=1) sys.exit(1) # start / webbrowser if os.name == "posix": # # Fork off a child and use it to start the # Neubot agent. The parent process will # open the browser, if needed. Otherwise # it will exit. # if not running and start: if os.fork() == 0: from neubot import agent arguments = [ argv[0] ] agent.main(arguments) sys.exit(0) # # It's not wise at all to open the browser when # we are running as root. Assume that when we # are root the user wants just to start the agent. # if webgui and "DISPLAY" in os.environ: if os.getuid() != 0: from neubot.main import browser browser.open_patient("127.0.0.1", "9774") elif os.name == "nt": if webgui: from neubot.main import browser if not running and start: browser.open_patient("127.0.0.1", "9774", True) else: browser.open_patient("127.0.0.1", "9774") if not running and start: from neubot import agent agent.main([argv[0]]) else: sys.stderr.write("Your operating system is not supported\n") sys.exit(1)