def __init__(self, args): self._original_excepthook = sys.excepthook self.args = args if args.creds_file: try: with open(args.creds_file, 'r') as fp: creds = json.loads(fp.read()) username = creds.get('username') password = creds.get('password') session_cookie = login_user(CONF.getServerURI(), username, password) if session_cookie: logger.info('Login successful') CONF.setDBUser(username) CONF.setDBSessionCookies(session_cookie) else: logger.error('Login failed') except (IOError, ValueError): logger.error("Credentials file couldn't be loaded") self._mappers_manager = MapperManager() pending_actions = Queue() self._model_controller = ModelController(self._mappers_manager, pending_actions) self._plugin_manager = PluginManager( os.path.join(CONF.getConfigPath(), "plugins"), pending_actions=pending_actions, ) self._workspace_manager = WorkspaceManager( self._mappers_manager) # Create a PluginController and send this to UI selected. self._plugin_controller = PluginController( 'PluginController', self._plugin_manager, self._mappers_manager, pending_actions ) if self.args.cli: self.app = CliApp(self._workspace_manager, self._plugin_controller) if self.args.keep_old: CONF.setMergeStrategy("old") else: CONF.setMergeStrategy("new") else: self.app = UiFactory.create(self._model_controller, self._plugin_manager, self._workspace_manager, self._plugin_controller, self.args.gui) self.timer = TimerClass() self.timer.start()
class WebServer(object): UI_URL_PATH = '_ui' API_URL_PATH = '_api' WEB_UI_LOCAL_PATH = os.path.join(faraday.server.config.FARADAY_BASE, 'server/www') def __init__(self, enable_ssl=False): logger.info('Starting web server at {}://{}:{}/'.format( 'https' if enable_ssl else 'http', faraday.server.config.faraday_server.bind_address, faraday.server.config.faraday_server.port)) self.__ssl_enabled = enable_ssl self.__websocket_ssl_enabled = faraday.server.config.websocket_ssl.enabled self.__websocket_port = faraday.server.config.faraday_server.websocket_port or 9000 self.__config_server() self.__build_server_tree() def __config_server(self): self.__bind_address = faraday.server.config.faraday_server.bind_address self.__listen_port = int(faraday.server.config.faraday_server.port) if self.__ssl_enabled: self.__listen_port = int(faraday.server.config.ssl.port) def __load_ssl_certs(self): certs = (faraday.server.config.ssl.keyfile, faraday.server.config.ssl.certificate) if not all(certs): logger.critical( "HTTPS request but SSL certificates are not configured") exit(1) # Abort web-server startup return ssl.DefaultOpenSSLContextFactory(*certs) def __build_server_tree(self): self.__root_resource = self.__build_web_resource() self.__root_resource.putChild(WebServer.UI_URL_PATH, self.__build_web_redirect()) self.__root_resource.putChild(WebServer.API_URL_PATH, self.__build_api_resource()) def __build_web_redirect(self): return FaradayRedirectResource('/') def __build_web_resource(self): return FileWithoutDirectoryListing(WebServer.WEB_UI_LOCAL_PATH) def __build_api_resource(self): return FaradayWSGIResource(reactor, reactor.getThreadPool(), app) def __build_websockets_resource(self): websocket_port = int( faraday.server.config.faraday_server.websocket_port) url = '{0}:{1}'.format(self.__bind_address, websocket_port) if self.__websocket_ssl_enabled: url = 'wss://' + url else: url = 'ws://' + url # logger.info(u"Websocket listening at {url}".format(url=url)) logger.info( 'Starting websocket server at port {0} with bind address {1}. ' 'SSL {2}'.format(self.__websocket_port, self.__bind_address, self.__ssl_enabled)) factory = WorkspaceServerFactory(url=url) factory.protocol = BroadcastServerProtocol return factory def install_signal(self): for sig in (SIGABRT, SIGILL, SIGINT, SIGSEGV, SIGTERM): signal(sig, SIG_DFL) def run(self): def signal_handler(*args): logger.info('Received SIGTERM, shutting down.') logger.info("Stopping threads, please wait...") # teardown() self.raw_report_processor.stop() self.timer.stop() log_path = os.path.join(CONST_FARADAY_HOME_PATH, 'logs', 'access-logging.log') site = twisted.web.server.Site(self.__root_resource, logPath=log_path, logFormatter=proxiedLogFormatter) site.displayTracebacks = False if self.__ssl_enabled: ssl_context = self.__load_ssl_certs() self.__listen_func = functools.partial(reactor.listenSSL, contextFactory=ssl_context) else: self.__listen_func = reactor.listenTCP try: self.install_signal() # start threads and processes self.raw_report_processor = RawReportProcessor() self.raw_report_processor.start() self.timer = TimerClass() self.timer.start() # web and static content self.__listen_func(self.__listen_port, site, interface=self.__bind_address) # websockets if faraday.server.config.websocket_ssl.enabled: contextFactory = ssl.DefaultOpenSSLContextFactory( faraday.server.config.websocket_ssl.keyfile.strip('\''), faraday.server.config.websocket_ssl.certificate.strip( '\'')) try: listenWS(self.__build_websockets_resource(), interface=self.__bind_address, contextFactory=contextFactory) except error.CannotListenError: logger.warn( 'Could not start websockets, address already open. This is ok is you wan to run multiple instances.' ) except Exception as ex: logger.warn( 'Could not start websocket, error: {}'.format(ex)) else: try: listenWS(self.__build_websockets_resource(), interface=self.__bind_address) except error.CannotListenError: logger.warn( 'Could not start websockets, address already open. This is ok is you wan to run multiple instances.' ) except Exception as ex: logger.warn( 'Could not start websocket, error: {}'.format(ex)) logger.info('Faraday Server is ready') reactor.addSystemEventTrigger('before', 'shutdown', signal_handler) reactor.run() except error.CannotListenError as e: logger.error(str(e)) sys.exit(1) except Exception as e: logger.error( 'Something went wrong when trying to setup the Web UI') logger.exception(e) sys.exit(1)
class MainApplication(object): def __init__(self, args): self._original_excepthook = sys.excepthook self.args = args if args.creds_file: try: with open(args.creds_file, 'r') as fp: creds = json.loads(fp.read()) username = creds.get('username') password = creds.get('password') session_cookie = login_user(CONF.getServerURI(), username, password) if session_cookie: logger.info('Login successful') CONF.setDBUser(username) CONF.setDBSessionCookies(session_cookie) else: logger.error('Login failed') except (IOError, ValueError): logger.error("Credentials file couldn't be loaded") self._mappers_manager = MapperManager() pending_actions = Queue() self._model_controller = ModelController(self._mappers_manager, pending_actions) self._plugin_manager = PluginManager( os.path.join(CONF.getConfigPath(), "plugins"), pending_actions=pending_actions, ) self._workspace_manager = WorkspaceManager( self._mappers_manager) # Create a PluginController and send this to UI selected. self._plugin_controller = PluginController( 'PluginController', self._plugin_manager, self._mappers_manager, pending_actions ) if self.args.cli: self.app = CliApp(self._workspace_manager, self._plugin_controller) if self.args.keep_old: CONF.setMergeStrategy("old") else: CONF.setMergeStrategy("new") else: self.app = UiFactory.create(self._model_controller, self._plugin_manager, self._workspace_manager, self._plugin_controller, self.args.gui) self.timer = TimerClass() self.timer.start() def on_connection_lost(self): """All it does is send a notification to the notification center""" faraday.client.model.guiapi.notification_center.DBConnectionProblem() def enableExceptHook(self): sys.excepthook = exception_handler installThreadExcepthook() def start(self): try: signal.signal(signal.SIGINT, self.ctrlC) faraday.client.model.api.devlog("Starting application...") faraday.client.model.api.devlog("Setting up remote API's...") if not self.args.workspace: workspace = CONF.getLastWorkspace() self.args.workspace = workspace faraday.client.model.api.setUpAPIs( self._model_controller, self._workspace_manager, CONF.getApiConInfoHost(), CONF.getApiConInfoPort()) faraday.client.model.guiapi.setUpGUIAPIs(self._model_controller) faraday.client.model.api.devlog("Starting model controller daemon...") self._model_controller.start() faraday.client.model.api.startAPIServer() restapi.startAPIs( self._plugin_controller, self._model_controller, CONF.getApiConInfoHost(), CONF.getApiRestfulConInfoPort() ) faraday.client.model.api.devlog("Faraday ready...") exit_code = self.app.run(self.args) except Exception as exception: print("There was an error while starting Faraday:") print("*" * 3) print(exception) # instead of traceback.print_exc() print("*" * 3) exit_code = -1 finally: return self.__exit(exit_code) def __exit(self, exit_code=0): """ Exits the application with the provided code. It also waits until all app threads end. """ faraday.client.model.api.log("Closing Faraday...") faraday.client.model.api.devlog("stopping model controller thread...") faraday.client.model.api.stopAPIServer() restapi.stopServer() self._model_controller.stop() if self._model_controller.isAlive(): # runs only if thread has started, i.e. self._model_controller.start() is run first self._model_controller.join() self.timer.stop() faraday.client.model.api.devlog("Waiting for controller threads to end...") return exit_code def quit(self): """ Redefined quit handler to nicely end up things """ self.app.quit() def ctrlC(self, signal, frame): logger.info("Exiting...") self.app.quit()
def run(self): def signal_handler(*args): logger.info('Received SIGTERM, shutting down.') logger.info("Stopping threads, please wait...") # teardown() self.raw_report_processor.stop() self.timer.stop() log_path = os.path.join(CONST_FARADAY_HOME_PATH, 'logs', 'access-logging.log') site = twisted.web.server.Site(self.__root_resource, logPath=log_path, logFormatter=proxiedLogFormatter) site.displayTracebacks = False if self.__ssl_enabled: ssl_context = self.__load_ssl_certs() self.__listen_func = functools.partial(reactor.listenSSL, contextFactory=ssl_context) else: self.__listen_func = reactor.listenTCP try: self.install_signal() # start threads and processes self.raw_report_processor = RawReportProcessor() self.raw_report_processor.start() self.timer = TimerClass() self.timer.start() # web and static content self.__listen_func(self.__listen_port, site, interface=self.__bind_address) # websockets if faraday.server.config.websocket_ssl.enabled: contextFactory = ssl.DefaultOpenSSLContextFactory( faraday.server.config.websocket_ssl.keyfile.strip('\''), faraday.server.config.websocket_ssl.certificate.strip( '\'')) try: listenWS(self.__build_websockets_resource(), interface=self.__bind_address, contextFactory=contextFactory) except error.CannotListenError: logger.warn( 'Could not start websockets, address already open. This is ok is you wan to run multiple instances.' ) except Exception as ex: logger.warn( 'Could not start websocket, error: {}'.format(ex)) else: try: listenWS(self.__build_websockets_resource(), interface=self.__bind_address) except error.CannotListenError: logger.warn( 'Could not start websockets, address already open. This is ok is you wan to run multiple instances.' ) except Exception as ex: logger.warn( 'Could not start websocket, error: {}'.format(ex)) logger.info('Faraday Server is ready') reactor.addSystemEventTrigger('before', 'shutdown', signal_handler) reactor.run() except error.CannotListenError as e: logger.error(str(e)) sys.exit(1) except Exception as e: logger.error( 'Something went wrong when trying to setup the Web UI') logger.exception(e) sys.exit(1)