def main(args): """ Main function """ if not system.has_enough_privs(): sys.exit('FATAL: you must be root') common.main("agent", "Run in background, periodically run tests", args) conf = CONFIG.copy() privacy.complain_if_needed() BACKEND.use_backend("neubot") BACKEND.datadir_init() # FIXME We're ignoring agent.api.{address,port} that are now # deprecated and should be removed soon. background_api.start_api() if conf["agent.daemonize"]: LOG.redirect() system.go_background() if conf["agent.use_syslog"]: LOG.redirect() # # When we run as an agent we also save logs into # the database, to easily access and show them via # the web user interface. # LOG.use_database() logging.info('%s for POSIX: starting up', utils_version.PRODUCT) system.drop_privileges() if os.getuid() == 0 or os.geteuid() == 0: logging.error('agent: still running as root') os._exit(1) if conf["agent.rendezvous"]: BACKGROUND_RENDEZVOUS.start() POLLER.loop() logging.info('%s for POSIX: shutting down', utils_version.PRODUCT) LOG.writeback() # # Make sure that we do not leave the database # in an inconsistent state. # DATABASE.close()
def connection(self): ''' Return connection to database ''' if not self.dbc: database_xxx.linux_fixup_databasedir() if self.path != ":memory:": self.path = system.check_database_path(self.path) logging.debug("* Database: %s", self.path) self.dbc = sqlite3.connect(self.path) # # To avoid the need to map at hand columns in # a row with the sql schema, which is as error # prone as driving drunk. # self.dbc.row_factory = sqlite3.Row # # On POSIX systems, neubot (initially) runs as root, to ensure that # database location, ownership and permissions are OK (as well as # to bind privileged ports). But neubot can also be started by # normal users. In this case, mark the database as readonly since # write operation are going to raise exceptions. # if not system.has_enough_privs(): logging.warning('database: opening database in readonly mode') self.readonly = True return self.dbc # # Migrate MUST be before table creation. This # is safe because table creation always uses # the IF NOT EXISTS clause. And this is needed # because otherwise we cannot migrate archived # databases (whose version number is old). # The exception is the config table which must # be present because migrate() looks at it. # table_config.create(self.dbc) migrate.migrate(self.dbc) migrate2.migrate(self.dbc) table_speedtest.create(self.dbc) table_geoloc.create(self.dbc) table_bittorrent.create(self.dbc) table_log.create(self.dbc) table_raw.create(self.dbc) return self.dbc
def main(args): """ Starts the server module """ if not system.has_enough_privs(): sys.exit('FATAL: you must be root') try: options, arguments = getopt.getopt(args[1:], 'A:b:D:dv') except getopt.error: sys.exit(USAGE) if arguments: sys.exit(USAGE) address = ':: 0.0.0.0' backend = 'mlab' for name, value in options: if name == '-A': address = value elif name == '-b': backend = value elif name == '-D': name, value = value.split('=', 1) if name not in VALID_MACROS: sys.exit(USAGE) if name != 'server.datadir': # XXX value = int(value) SETTINGS[name] = value elif name == '-d': SETTINGS['server.daemonize'] = 0 elif name == '-v': CONFIG['verbose'] = 1 logging.debug('server: using backend: %s... in progress', backend) if backend == 'mlab': BACKEND.datadir_init(None, SETTINGS['server.datadir']) BACKEND.use_backend('mlab') elif backend == 'neubot': DATABASE.connect() BACKEND.use_backend('neubot') elif backend == 'volatile': BACKEND.use_backend('volatile') else: BACKEND.use_backend('null') logging.debug('server: using backend: %s... complete', backend) for name, value in SETTINGS.items(): CONFIG[name] = value conf = CONFIG.copy() # # Configure our global HTTP server and make # sure that we don't provide filesystem access # even by mistake. # conf["http.server.rootdir"] = "" HTTP_SERVER.configure(conf) # # New-new style: don't bother with abstraction and start the f*****g # server by invoking its listen() method. # if CONFIG['server.raw']: logging.debug('server: starting raw server... in progress') RAW_SERVER_EX.listen((address, 12345), CONFIG['prefer_ipv6'], 0, '') logging.debug('server: starting raw server... complete') if conf['server.skype']: logging.debug('server: starting skype server... in progress') SKYPE_SERVER_EX.listen((":: 0.0.0.0", 45678), CONFIG['prefer_ipv6'], 0, '') logging.debug('server: starting skype server... complete') # # New-style modules are started just setting a # bunch of conf[] variables and then invoking # their run() method in order to kick them off. # This is now depricated in favor of the new- # new style described above. # if conf["server.negotiate"]: negotiate.run(POLLER, conf) if conf["server.bittorrent"]: conf["bittorrent.address"] = address conf["bittorrent.listen"] = True conf["bittorrent.negotiate"] = True bittorrent.run(POLLER, conf) if conf['server.speedtest']: #conf['speedtest.listen'] = 1 # Not yet #conf['speedtest.negotiate'] = 1 # Not yet neubot.speedtest.wrapper.run(POLLER, conf) # Migrating from old style to new style if conf["server.rendezvous"]: #conf["rendezvous.listen"] = True # Not yet neubot.rendezvous.server.run() # # Historically Neubot runs on port 9773 and # 8080 but we would like to switch to port 80 # in the long term period, because it's rare # that they filter it. # OTOH it looks like it's not possible to # do that easily w/ M-Lab because the port # is already taken. # ports = (80, 8080, 9773) for port in ports: HTTP_SERVER.listen((address, port)) # # Start server-side API for Nagios plugin # to query the state of the server. # functionalities. # if conf["server.sapi"]: server = ServerSideAPI(POLLER) server.configure(conf) HTTP_SERVER.register_child(server, "/sapi") # # Create localhost-only debug server # if CONFIG['server.debug']: logging.info('server: Starting debug server at {127.0.0.1,::1}:9774') server = DebugAPI(POLLER) server.configure(conf) server.listen(('127.0.0.1 ::1', 9774)) # Probe existing modules and ask them to attach to us utils_modules.modprobe(None, "server", { "http_server": HTTP_SERVER, "negotiate_server": NEGOTIATE_SERVER, }) # # Go background and drop privileges, # then enter into the main loop. # if conf["server.daemonize"]: LOG.redirect() system.go_background() sigterm_handler = lambda signo, frame: POLLER.break_loop() signal.signal(signal.SIGTERM, sigterm_handler) logging.info('Neubot server -- starting up') system.drop_privileges() POLLER.loop() logging.info('Neubot server -- shutting down') utils_posix.remove_pidfile('/var/run/neubot.pid')
def main(args): """ Starts the server module """ if not system.has_enough_privs(): sys.exit("FATAL: you must be root") try: options, arguments = getopt.getopt(args[1:], "b:D:dv") except getopt.error: sys.exit(USAGE) if arguments: sys.exit(USAGE) backend = "mlab" for name, value in options: if name == "-b": backend = value elif name == "-D": name, value = value.split("=", 1) if name not in VALID_MACROS: sys.exit(USAGE) SETTINGS[name] = int(value) elif name == "-d": SETTINGS["server.daemonize"] = 0 elif name == "-v": CONFIG["verbose"] = 1 logging.debug("server: using backend: %s... in progress", backend) if backend == "mlab": FILESYS.datadir_init() BACKEND.use_backend("mlab") elif backend == "neubot": DATABASE.connect() BACKEND.use_backend("neubot") else: BACKEND.use_backend("null") logging.debug("server: using backend: %s... complete", backend) for name, value in SETTINGS.items(): CONFIG[name] = value conf = CONFIG.copy() # # Configure our global HTTP server and make # sure that we don't provide filesystem access # even by mistake. # conf["http.server.rootdir"] = "" HTTP_SERVER.configure(conf) # # New-new style: don't bother with abstraction and start the f*****g # server by invoking its listen() method. # if CONFIG["server.raw"]: logging.debug("server: starting raw server... in progress") RAW_SERVER_EX.listen((":: 0.0.0.0", 12345), CONFIG["prefer_ipv6"], 0, "") logging.debug("server: starting raw server... complete") # # New-style modules are started just setting a # bunch of conf[] variables and then invoking # their run() method in order to kick them off. # if conf["server.negotiate"]: negotiate.run(POLLER, conf) if conf["server.bittorrent"]: conf["bittorrent.listen"] = True conf["bittorrent.negotiate"] = True bittorrent.run(POLLER, conf) if conf["server.speedtest"]: # conf['speedtest.listen'] = 1 # Not yet # conf['speedtest.negotiate'] = 1 # Not yet neubot.speedtest.wrapper.run(POLLER, conf) # Migrating from old style to new style if conf["server.rendezvous"]: # conf["rendezvous.listen"] = True # Not yet neubot.rendezvous.server.run() # # Historically Neubot runs on port 9773 and # 8080 but we would like to switch to port 80 # in the long term period, because it's rare # that they filter it. # OTOH it looks like it's not possible to # do that easily w/ M-Lab because the port # is already taken. # address = ":: 0.0.0.0" ports = (80, 8080, 9773) for port in ports: HTTP_SERVER.listen((address, port)) # # Start server-side API for Nagios plugin # to query the state of the server. # functionalities. # if conf["server.sapi"]: server = ServerSideAPI(POLLER) server.configure(conf) HTTP_SERVER.register_child(server, "/sapi") # # Create localhost-only debug server # if CONFIG["server.debug"]: logging.info("server: Starting debug server at {127.0.0.1,::1}:9774") server = DebugAPI(POLLER) server.configure(conf) server.listen(("127.0.0.1 ::1", 9774)) # # Go background and drop privileges, # then enter into the main loop. # if conf["server.daemonize"]: LOG.redirect() system.go_background() system.drop_privileges() POLLER.loop()