diff --git a/controller/opt/server.py b/controller/opt/server.py index c34f0a2..2fa5b44 100644 --- a/controller/opt/server.py +++ b/controller/opt/server.py @@ -5,11 +5,12 @@ from tornado.ioloop import IOLoop from tornado.web import RequestHandler, Application from tfw.builtins import FSMAwareEventHandler +from tfw.main import EventHandlerFactory class ControllerPostHandler(RequestHandler): - # pylint: disable=abstract-method - def initialize(self, **kwargs): # pylint: disable=arguments-differ + # pylint: disable=abstract-method,attribute-defined-outside-init,unused-argument + def initialize(self, **kwargs): self.controller = kwargs['controller'] def post(self, *args, **kwargs): @@ -26,6 +27,8 @@ class ControllerEventHandler(FSMAwareEventHandler): if __name__ == '__main__': controller = ControllerEventHandler('controller') + controller_eh = EventHandlerFactory().build(controller) + application = Application([( f'/{os.environ["SECRET"]}', ControllerPostHandler, diff --git a/solvable/src/custom_event_handlers.py b/solvable/src/custom_event_handlers.py index ca9749b..0789dba 100644 --- a/solvable/src/custom_event_handlers.py +++ b/solvable/src/custom_event_handlers.py @@ -2,25 +2,25 @@ import logging from ast import literal_eval from tfw.components import MessageSender -from tfw.builtins import TFWServerUplinkConnector -from tfw.builtins import EventHandler, FSMAwareEventHandler, TerminalCommandsEventHandler +from tfw.builtins import TerminalCommandsEventHandler +from tfw.main import TFWUplinkConnector + LOG = logging.getLogger(__name__) -class CenatorEventHandler(EventHandler): +class CenatorEventHandler: + keys = ['history.bash'] + # pylint: disable=no-self-use """ Logs commands executed in terminal to messages and invokes an additional callback function to handle special commands. !! Please remove from production code. !! """ - def __init__(self, key): - super().__init__(key) - - def handle_event(self, message): + def handle_event(self, message, server_connector): command = message['value'] LOG.debug('User executed command: "%s"', command) - MessageSender(self.server_connector).send('JOHN CENA', f'You\'ve executed "{command}"') + MessageSender(server_connector).send('JOHN CENA', f'You\'ve executed "{command}"') class TestCommandsEventHandler(TerminalCommandsEventHandler): @@ -40,7 +40,7 @@ class TestCommandsEventHandler(TerminalCommandsEventHandler): """ if not args: message_template = """'{"key": "", "data": {"command": ""}}'""" - TFWServerUplinkConnector().send_message({ + TFWUplinkConnector().send_message({ 'key': 'shell', 'data': { 'command': 'write', @@ -48,24 +48,22 @@ class TestCommandsEventHandler(TerminalCommandsEventHandler): } }) else: - TFWServerUplinkConnector().send_message(literal_eval(args[0])) + TFWUplinkConnector().send_message(literal_eval(args[0])) -class MessageFSMStepsEventHandler(FSMAwareEventHandler): +class MessageFSMStepsEventHandler: + # pylint: disable=no-self-use """ This example EventHandler is capable of detecting FSM state. !! Please remove from production code !! """ - def handle_event(self, message): - pass - - def handle_fsm_step(self, **kwargs): + def handle_event(self, message, server_connector): """ When the FSM steps this method is invoked. Receives a 'data' field from an fsm_update message as kwargs. """ - MessageSender(self.server_connector).send( + MessageSender(server_connector).send( 'FSM info', - f'FSM has stepped from state "{kwargs["last_event"]["from_state"]}" ' - f'to state "{kwargs["current_state"]}" in response to trigger "{kwargs["last_event"]["trigger"]}"' + f'FSM has stepped from state "{message["last_event"]["from_state"]}" ' + f'to state "{message["current_state"]}" in response to trigger "{message["last_event"]["trigger"]}"' ) diff --git a/solvable/src/event_handler_main.py b/solvable/src/event_handler_main.py index b31bd2d..fc8e588 100644 --- a/solvable/src/event_handler_main.py +++ b/solvable/src/event_handler_main.py @@ -5,73 +5,87 @@ from functools import partial from tornado.ioloop import IOLoop from tfw.fsm import YamlFSM +from tfw.event_handlers import FSMAwareEventHandler from tfw.builtins import IdeEventHandler, TerminalEventHandler, FrontendEventHandler from tfw.builtins import LogMonitoringEventHandler, ProcessManagingEventHandler from tfw.builtins import DirectorySnapshottingEventHandler, FSMManagingEventHandler -from tfw.config import TFWENV +from tfw.main import EventHandlerFactory, setup_signal_handlers from tfw.logging import Log, Logger, LogFormatter, VerboseLogFormatter +from tfw.config import TFWENV from tao.config import TAOENV from custom_event_handlers import MessageFSMStepsEventHandler from custom_event_handlers import CenatorEventHandler, TestCommandsEventHandler -from signal_handling import setup_signal_handlers + LOG = logging.getLogger(__name__) def main(): - # pylint: disable=unused-variable + # pylint: disable=unused-variable,too-many-locals Logger([ Log(stderr, LogFormatter(20)), Log(TFWENV.LOGFILE, VerboseLogFormatter()) ]).start() + eh_factory = EventHandlerFactory() # TFW component EventHandlers (builtins, required for their respective functionalities) fsm = FSMManagingEventHandler( # TFW FSM - key='fsm', fsm_type=partial( YamlFSM, 'test_fsm.yml', {} # jinja2 variables, use empty dict to enable jinja2 parsing without any variables ) ) + fsm_eh = eh_factory.build(fsm) + ide = IdeEventHandler( # Web IDE backend - key='ide', allowed_directories=[TFWENV.IDE_WD, TFWENV.WEBSERVICE_DIR], directory=TFWENV.IDE_WD, exclude=['*.pyc'] ) - terminal = TerminalEventHandler( # Web shell backend - key='shell' - ) - cenator = CenatorEventHandler('history.bash') # Reacts to terminal commands - commands = TestCommandsEventHandler( # Catches special commands - key='history.bash', - bashrc=f'/home/{TAOENV.USER}/.bashrc' - ) + ide_eh = eh_factory.build(ide) + + terminal = TerminalEventHandler() # Web shell backend + terminal_eh = eh_factory.build(terminal) + processmanager = ProcessManagingEventHandler( # Handles 'deploy' button clicks - key='processmanager', log_tail=2000 ) + processmanager_eh = eh_factory.build(processmanager) + logmonitor = LogMonitoringEventHandler( # Sends live logs of webservice process to frontend - key='logmonitor', process_name='webservice', log_tail=2000 ) + logmonitor_eh = eh_factory.build(logmonitor) + snapshot = DirectorySnapshottingEventHandler( # Manages filesystem snapshots of directories - key='snapshot', directories=[ TFWENV.IDE_WD, TFWENV.WEBSERVICE_DIR ] ) + snapshot_eh = eh_factory.build(snapshot) + frontend = FrontendEventHandler() # Proxies frontend API calls to frontend + frontend_eh = eh_factory.build(frontend) # Your custom event handlers - message_fsm_steps_eh = MessageFSMStepsEventHandler( - key='test' + cenator = CenatorEventHandler() + cenator_eh = eh_factory.build(cenator) + + message_fsm_steps = MessageFSMStepsEventHandler() + message_fsm_steps_eh = eh_factory.build( + message_fsm_steps, + event_handler_type=FSMAwareEventHandler ) + commands = TestCommandsEventHandler( # Catches special commands + bashrc=f'/home/{TAOENV.USER}/.bashrc' + ) + commands_eh = eh_factory.build(commands) + setup_signal_handlers() IOLoop.instance().start() diff --git a/solvable/src/pipe_io_main.py b/solvable/src/pipe_io_main.py index 27d886f..7a44dc3 100644 --- a/solvable/src/pipe_io_main.py +++ b/solvable/src/pipe_io_main.py @@ -6,14 +6,8 @@ from tornado.ioloop import IOLoop from tfw.builtins import PipeIOEventHandler from tfw.config import TFWENV from tfw.logging import Log, Logger, LogFormatter, VerboseLogFormatter +from tfw.main import EventHandlerFactory, setup_signal_handlers -from pipe_io_auxlib import ( - SignMessagePipeIOEventHandler, VerifyMessagePipeIOEventHandler, - BotPipeIOEventHandler, - DeployPipeIOEventHandler, IdePipeIOEventHandler, - FSMPipeIOEventHandler -) -from signal_handling import setup_signal_handlers LOG = logging.getLogger(__name__) @@ -25,46 +19,14 @@ def main(): Log(TFWENV.LOGFILE, VerboseLogFormatter()) ]).start() + eh_factory = EventHandlerFactory() + json_pipe = PipeIOEventHandler( - '', - '/tmp/tfw_json_send', - '/tmp/tfw_json_recv' + '/tmp/tfw_send', + '/tmp/tfw_recv' ) + json_pipe_eh = eh_factory.build(json_pipe) - sign_pipe = SignMessagePipeIOEventHandler( - '/tmp/tfw_sign_send', - '/tmp/tfw_sign_recv', - forwarding=True - ) - - verify_pipe = VerifyMessagePipeIOEventHandler( - '/tmp/tfw_verify_send', - '/tmp/tfw_verify_recv' - ) - - bot_pipe = BotPipeIOEventHandler( - '/tmp/tfw_bot_send', - '/tmp/tfw_bot_recv', - permissions=0o666 - ) - - deploy_pipe = DeployPipeIOEventHandler( - '/tmp/tfw_deploy_send', - '/tmp/tfw_deploy_recv', - 'webservice' - ) - - ide_pipe = IdePipeIOEventHandler( - '/tmp/tfw_ide_send', - '/tmp/tfw_ide_recv', - 'user_ops.py', - selected=True - ) - - fsm_pipe = FSMPipeIOEventHandler( - '/tmp/tfw_fsm_send', - '/tmp/tfw_fsm_recv' - ) setup_signal_handlers() IOLoop.instance().start() diff --git a/solvable/src/signal_handling.py b/solvable/src/signal_handling.py deleted file mode 100644 index 21294d2..0000000 --- a/solvable/src/signal_handling.py +++ /dev/null @@ -1,11 +0,0 @@ -from signal import signal, SIGTERM, SIGINT - -from tfw.builtins import EventHandler - - -def setup_signal_handlers(): - def stop(*_): - EventHandler.stop_all_instances() - exit(0) - signal(SIGTERM, stop) - signal(SIGINT, stop)