From 64ea7d8218523779c64e66d7a55e6017ea22c790 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Mon, 8 Jul 2019 20:12:12 +0200 Subject: [PATCH 01/18] Fix ZMQ socketopt call order --- lib/tfw/networking/server_connector.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tfw/networking/server_connector.py b/lib/tfw/networking/server_connector.py index e1ef1fe..88e9450 100644 --- a/lib/tfw/networking/server_connector.py +++ b/lib/tfw/networking/server_connector.py @@ -13,8 +13,8 @@ LOG = logging.getLogger(__name__) class ServerDownlinkConnector(): def __init__(self, connect_addr): self._zmq_sub_socket = zmq.Context.instance().socket(zmq.SUB) - self._zmq_sub_socket.connect(connect_addr) self._zmq_sub_socket.setsockopt(zmq.RCVHWM, 0) + self._zmq_sub_socket.connect(connect_addr) self._zmq_sub_stream = ZMQStream(self._zmq_sub_socket) self.subscribe = partial(self._zmq_sub_socket.setsockopt_string, zmq.SUBSCRIBE) @@ -31,8 +31,8 @@ class ServerDownlinkConnector(): class ServerUplinkConnector(): def __init__(self, connect_addr): self._zmq_push_socket = zmq.Context.instance().socket(zmq.PUSH) - self._zmq_push_socket.connect(connect_addr) self._zmq_push_socket.setsockopt(zmq.SNDHWM, 0) + self._zmq_push_socket.connect(connect_addr) def send_message(self, message, scope=Scope.ZMQ): message['scope'] = scope.value From e5dee3a1b3b453ed406d6f27ddeace80cffff0fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Tue, 9 Jul 2019 09:12:21 +0200 Subject: [PATCH 02/18] Remove leftover parentheses --- lib/tfw/networking/event_handler_connector.py | 4 ++-- lib/tfw/networking/server_connector.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/tfw/networking/event_handler_connector.py b/lib/tfw/networking/event_handler_connector.py index 60cbb94..74b6270 100644 --- a/lib/tfw/networking/event_handler_connector.py +++ b/lib/tfw/networking/event_handler_connector.py @@ -8,7 +8,7 @@ from .serialization import serialize_tfw_msg, with_deserialize_tfw_msg LOG = logging.getLogger(__name__) -class EventHandlerDownlinkConnector(): +class EventHandlerDownlinkConnector: def __init__(self, bind_addr): self._zmq_pull_socket = zmq.Context.instance().socket(zmq.PULL) self._zmq_pull_socket.setsockopt(zmq.RCVHWM, 0) @@ -24,7 +24,7 @@ class EventHandlerDownlinkConnector(): self._zmq_pull_stream.close() -class EventHandlerUplinkConnector(): +class EventHandlerUplinkConnector: def __init__(self, bind_addr): self._zmq_pub_socket = zmq.Context.instance().socket(zmq.PUB) self._zmq_pub_socket.setsockopt(zmq.SNDHWM, 0) diff --git a/lib/tfw/networking/server_connector.py b/lib/tfw/networking/server_connector.py index 88e9450..da407ac 100644 --- a/lib/tfw/networking/server_connector.py +++ b/lib/tfw/networking/server_connector.py @@ -10,7 +10,7 @@ from .serialization import serialize_tfw_msg, with_deserialize_tfw_msg LOG = logging.getLogger(__name__) -class ServerDownlinkConnector(): +class ServerDownlinkConnector: def __init__(self, connect_addr): self._zmq_sub_socket = zmq.Context.instance().socket(zmq.SUB) self._zmq_sub_socket.setsockopt(zmq.RCVHWM, 0) @@ -28,7 +28,7 @@ class ServerDownlinkConnector(): self._zmq_sub_stream.close() -class ServerUplinkConnector(): +class ServerUplinkConnector: def __init__(self, connect_addr): self._zmq_push_socket = zmq.Context.instance().socket(zmq.PUSH) self._zmq_push_socket.setsockopt(zmq.SNDHWM, 0) From 84a28a1582eea4dec0e8167967dcfb13fb761b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Tue, 9 Jul 2019 11:02:45 +0200 Subject: [PATCH 03/18] Remove unused rate limiter classes (sad to see you go) --- lib/tfw/decorators/rate_limiter.py | 98 ------------------------------ 1 file changed, 98 deletions(-) delete mode 100644 lib/tfw/decorators/rate_limiter.py diff --git a/lib/tfw/decorators/rate_limiter.py b/lib/tfw/decorators/rate_limiter.py deleted file mode 100644 index 5f8e253..0000000 --- a/lib/tfw/decorators/rate_limiter.py +++ /dev/null @@ -1,98 +0,0 @@ -from functools import wraps, partial -from time import time, sleep - -from tfw.decorators.lazy_property import lazy_property - - -class RateLimiter: - """ - Decorator class for rate limiting, blocking. - - When applied to a function this decorator will apply rate limiting - if the function is invoked more frequently than rate_per_seconds. - - By default rate limiting means sleeping until the next invocation time - as per __init__ parameter rate_per_seconds. - - Note that this decorator BLOCKS THE THREAD it is being executed on, - so it is only acceptable for stuff running on a separate thread. - - If this is no good for you please refer to AsyncRateLimiter in this module, - which is designed not to block and use the IOLoop it is being called from. - """ - def __init__(self, rate_per_second): - """ - :param rate_per_second: max frequency the decorated method should be - invoked with - """ - self.min_interval = 1 / float(rate_per_second) - self.fun = None - self.last_call = time() - - def action(self, seconds_to_next_call): - if seconds_to_next_call: - sleep(seconds_to_next_call) - self.fun() - - def __call__(self, fun): - @wraps(fun) - def wrapper(*args, **kwargs): - self.fun = partial(fun, *args, **kwargs) - limit_seconds = self._limit_rate() - self.action(limit_seconds) - return wrapper - - def _limit_rate(self): - seconds_since_last_call = time() - self.last_call - seconds_to_next_call = self.min_interval - seconds_since_last_call - - if seconds_to_next_call > 0: - return seconds_to_next_call - self.last_call = time() - return 0 - - -class AsyncRateLimiter(RateLimiter): - """ - Decorator class for rate limiting, non-blocking. - - The semantics of the rate limiting: - - unlike RateLimiter this decorator never blocks, instead it adds an async - callback version of the decorated function to the IOLoop - (to be executed after the rate limiting has expired). - - the timing works similarly to RateLimiter - """ - def __init__(self, rate_per_second, ioloop_factory): - """ - :param rate_per_second: max frequency the decorated method should be - invoked with - :param ioloop_factory: callable that should return an instance of the - IOLoop of the application - """ - self._ioloop_factory = ioloop_factory - self._ioloop = None - self._last_callback = None - - self._make_action_thread_safe() - super().__init__(rate_per_second=rate_per_second) - - def _make_action_thread_safe(self): - self.action = partial(self.ioloop.add_callback, self.action) - - @lazy_property - def ioloop(self): - return self._ioloop_factory() - - def action(self, seconds_to_next_call): - # pylint: disable=method-hidden - if self._last_callback: - self.ioloop.remove_timeout(self._last_callback) - - self._last_callback = self.ioloop.call_later( - seconds_to_next_call, - self.fun_with_debounce - ) - - def fun_with_debounce(self): - self.last_call = time() - self.fun() From f1679ffb502cfbd068b89713768716cfe1d27324 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Wed, 10 Jul 2019 14:26:12 +0200 Subject: [PATCH 04/18] Add new EventHandler stuff as per interface segregation principle --- lib/tfw/event_handlers/event_handler.py | 27 ++++ .../event_handlers/event_handler_factory.py | 51 ++++++ lib/tfw/event_handlers/test_event_handler.py | 147 ++++++++++++++++++ 3 files changed, 225 insertions(+) create mode 100644 lib/tfw/event_handlers/event_handler.py create mode 100644 lib/tfw/event_handlers/event_handler_factory.py create mode 100644 lib/tfw/event_handlers/test_event_handler.py diff --git a/lib/tfw/event_handlers/event_handler.py b/lib/tfw/event_handlers/event_handler.py new file mode 100644 index 0000000..a75381e --- /dev/null +++ b/lib/tfw/event_handlers/event_handler.py @@ -0,0 +1,27 @@ +class EventHandler: + _instances = set() + + def __init__(self, server_connector): + type(self)._instances.add(self) + self.server_connector = server_connector + + def start(self): + self.server_connector.register_callback(self._event_callback) + + def _event_callback(self, message): + self.handle_event(message, self.server_connector) + + def handle_event(self, message, server_connector): + raise NotImplementedError() + + @classmethod + def stop_all_instances(cls): + for instance in cls._instances: + instance.stop() + + def stop(self): + self.server_connector.close() + self.cleanup() + + def cleanup(self): + pass diff --git a/lib/tfw/event_handlers/event_handler_factory.py b/lib/tfw/event_handlers/event_handler_factory.py new file mode 100644 index 0000000..c3a6b18 --- /dev/null +++ b/lib/tfw/event_handlers/event_handler_factory.py @@ -0,0 +1,51 @@ +from contextlib import suppress + +from .event_handler import EventHandler + + +class EventHandlerFactoryBase: + def build(self, event_handler, *, keys=None): + analyzer = EventHandlerAnalyzer(event_handler, keys) + event_handler = self._build_from_callable(analyzer) + event_handler.start() + return event_handler + + def _build_from_callable(self, analyzer): + server_connector = self._build_server_connector() + server_connector.subscribe(analyzer.keys) + event_handler = EventHandler(server_connector) + event_handler.handle_event = analyzer.handle_event + with suppress(AttributeError): + event_handler.cleanup = analyzer.cleanup + return event_handler + + def _build_server_connector(self): + raise NotImplementedError() + + +class EventHandlerAnalyzer: + def __init__(self, event_handler, supplied_keys): + self._event_handler = event_handler + self._supplied_keys = supplied_keys + + @property + def keys(self): + if self._supplied_keys is None: + try: + return self._event_handler.keys + except AttributeError: + raise ValueError('No keys supplied!') + return self._supplied_keys + + @property + def handle_event(self): + try: + return self._event_handler.handle_event + except AttributeError: + if callable(self._event_handler): + return self._event_handler + raise ValueError('Object must implement handle_event or be a callable!') + + @property + def cleanup(self): + return self._event_handler.cleanup diff --git a/lib/tfw/event_handlers/test_event_handler.py b/lib/tfw/event_handlers/test_event_handler.py new file mode 100644 index 0000000..2005f51 --- /dev/null +++ b/lib/tfw/event_handlers/test_event_handler.py @@ -0,0 +1,147 @@ +# pylint: disable=redefined-outer-name +from secrets import token_urlsafe +from random import randint + +import pytest + +from .event_handler_factory import EventHandlerFactoryBase +from .event_handler import EventHandler + + +class MockEventHandlerFactory(EventHandlerFactoryBase): + def _build_server_connector(self): + return MockServerConnector() + + +class MockServerConnector: + def __init__(self): + self.keys = [] + self._on_message = None + + def register_callback(self, callback): + self._on_message = callback + + def simulate_message(self, message): + self._on_message(message) + + def subscribe(self, keys): + self.keys.extend(keys) + + def unsubscribe(self, keys): + for key in keys: + self.keys.remove(key) + + def send_message(self, message, scope=None): + pass + + def close(self): + pass + + +class MockEventHandler: + def __init__(self): + self.cleaned_up = False + + def handle_event(self, message, server_connector): + pass + + def cleanup(self): + self.cleaned_up = True + + +@pytest.fixture +def test_msg(): + yield token_urlsafe(randint(16, 64)) + + +@pytest.fixture +def test_keys(): + yield [ + token_urlsafe(randint(2, 8)) + for _ in range(randint(16, 32)) + ] + + +def test_build_from_object(test_keys, test_msg): + mock_eh = MockEventHandler() + def test_handle_event(message, server_connector): + raise RuntimeError(message, server_connector.keys) + mock_eh.handle_event = test_handle_event + eh = MockEventHandlerFactory().build(mock_eh, keys=test_keys) + + with pytest.raises(RuntimeError) as err: + eh.server_connector.simulate_message(test_msg) + msg, keys = err.args + assert msg == test_msg + assert keys == test_keys + assert not mock_eh.cleaned_up + eh.stop() + assert mock_eh.cleaned_up + + +def test_build_from_object_with_keys(test_keys): + mock_eh = MockEventHandler() + mock_eh.keys = test_keys # pylint: disable=attribute-defined-outside-init + eh = MockEventHandlerFactory().build(mock_eh) + + assert not mock_eh.cleaned_up + EventHandler.stop_all_instances() + assert mock_eh.cleaned_up + assert eh.server_connector.keys == test_keys + + +def test_build_from_callable(test_keys, test_msg): + class SomeCallable: + def __init__(self): + self.message = None + self.cleaned_up = False + def __call__(self, message, server_connector): + self.message = message + def cleanup(self): + self.cleaned_up = True + + mock_eh = SomeCallable() + eh = MockEventHandlerFactory().build(mock_eh, keys=test_keys) + + assert eh.server_connector.keys == test_keys + assert not mock_eh.message + eh.server_connector.simulate_message(test_msg) + assert mock_eh.message == test_msg + assert not mock_eh.cleaned_up + eh.stop() + assert mock_eh.cleaned_up + + +def test_build_from_function(test_keys, test_msg): + def some_function(message, server_connector): + raise RuntimeError(message, server_connector.keys) + eh = MockEventHandlerFactory().build(some_function, keys=test_keys) + + assert eh.server_connector.keys == test_keys + with pytest.raises(RuntimeError) as err: + eh.server_connector.simulate_message(test_msg) + msg, keys = err.args + assert msg == test_msg + assert keys == test_keys + + +def test_build_from_lambda(test_keys, test_msg): + def assert_messages_equal(msg): + assert msg == test_msg + fun = lambda msg, sc: assert_messages_equal(msg) + eh = MockEventHandlerFactory().build(fun, keys=test_keys) + eh.server_connector.simulate_message(test_msg) + + +def test_build_raises_if_no_key(): + eh = MockEventHandler() + with pytest.raises(ValueError): + MockEventHandlerFactory().build(eh) + + def test_handle_event(*_): + pass + with pytest.raises(ValueError): + MockEventHandlerFactory().build(test_handle_event) + + with pytest.raises(ValueError): + MockEventHandlerFactory().build(lambda msg, sc: None) From f73c059429e8d8121340f0bcee4b0c2756055c40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Thu, 11 Jul 2019 18:52:15 +0200 Subject: [PATCH 05/18] Improve EventHandlerFactoryBase --- .../event_handlers/event_handler_factory.py | 33 ++++--- lib/tfw/event_handlers/test_event_handler.py | 93 +++++++++++++------ 2 files changed, 87 insertions(+), 39 deletions(-) diff --git a/lib/tfw/event_handlers/event_handler_factory.py b/lib/tfw/event_handlers/event_handler_factory.py index c3a6b18..dc03c46 100644 --- a/lib/tfw/event_handlers/event_handler_factory.py +++ b/lib/tfw/event_handlers/event_handler_factory.py @@ -4,25 +4,34 @@ from .event_handler import EventHandler class EventHandlerFactoryBase: - def build(self, event_handler, *, keys=None): - analyzer = EventHandlerAnalyzer(event_handler, keys) - event_handler = self._build_from_callable(analyzer) - event_handler.start() - return event_handler - - def _build_from_callable(self, analyzer): + def build(self, event_handler, *, keys=None, event_handler_type=EventHandler): + builder = EventHandlerBuilder(event_handler, keys, event_handler_type) server_connector = self._build_server_connector() - server_connector.subscribe(analyzer.keys) - event_handler = EventHandler(server_connector) - event_handler.handle_event = analyzer.handle_event + real_event_handler = builder.build(server_connector) + event_handler.server_connector = server_connector with suppress(AttributeError): - event_handler.cleanup = analyzer.cleanup - return event_handler + event_handler.start() + real_event_handler.start() + return real_event_handler def _build_server_connector(self): raise NotImplementedError() +class EventHandlerBuilder: + def __init__(self, event_handler, supplied_keys, event_handler_type): + self._analyzer = EventHandlerAnalyzer(event_handler, supplied_keys) + self._event_handler_type = event_handler_type + + def build(self, server_connector): + server_connector.subscribe(*self._analyzer.keys) + event_handler = self._event_handler_type(server_connector) + event_handler.handle_event = self._analyzer.handle_event + with suppress(AttributeError): + event_handler.cleanup = self._analyzer.cleanup + return event_handler + + class EventHandlerAnalyzer: def __init__(self, event_handler, supplied_keys): self._event_handler = event_handler diff --git a/lib/tfw/event_handlers/test_event_handler.py b/lib/tfw/event_handlers/test_event_handler.py index 2005f51..edde537 100644 --- a/lib/tfw/event_handlers/test_event_handler.py +++ b/lib/tfw/event_handlers/test_event_handler.py @@ -1,4 +1,4 @@ -# pylint: disable=redefined-outer-name +# pylint: disable=redefined-outer-name,attribute-defined-outside-init from secrets import token_urlsafe from random import randint @@ -18,16 +18,16 @@ class MockServerConnector: self.keys = [] self._on_message = None - def register_callback(self, callback): - self._on_message = callback - def simulate_message(self, message): self._on_message(message) - def subscribe(self, keys): + def register_callback(self, callback): + self._on_message = callback + + def subscribe(self, *keys): self.keys.extend(keys) - def unsubscribe(self, keys): + def unsubscribe(self, *keys): for key in keys: self.keys.remove(key) @@ -38,17 +38,31 @@ class MockServerConnector: pass -class MockEventHandler: +class MockEventHandlerStub: def __init__(self): + self.server_connector = None + self.last_message = None self.cleaned_up = False + self.started = False - def handle_event(self, message, server_connector): - pass + def start(self): + self.started = True def cleanup(self): self.cleaned_up = True +class MockEventHandler(MockEventHandlerStub): + # pylint: disable=unused-argument + def handle_event(self, message, server_connector): + self.last_message = message + + +class MockCallable(MockEventHandlerStub): + def __call__(self, message, server_connector): + self.last_message = message + + @pytest.fixture def test_msg(): yield token_urlsafe(randint(16, 64)) @@ -63,12 +77,16 @@ def test_keys(): def test_build_from_object(test_keys, test_msg): - mock_eh = MockEventHandler() - def test_handle_event(message, server_connector): + mock_eh = MockEventHandlerStub() + def handle_event(message, server_connector): raise RuntimeError(message, server_connector.keys) - mock_eh.handle_event = test_handle_event + mock_eh.handle_event = handle_event + + assert not mock_eh.started eh = MockEventHandlerFactory().build(mock_eh, keys=test_keys) + assert mock_eh.started + assert mock_eh.server_connector is eh.server_connector with pytest.raises(RuntimeError) as err: eh.server_connector.simulate_message(test_msg) msg, keys = err.args @@ -79,34 +97,52 @@ def test_build_from_object(test_keys, test_msg): assert mock_eh.cleaned_up -def test_build_from_object_with_keys(test_keys): +def test_build_from_object_with_keys(test_keys, test_msg): mock_eh = MockEventHandler() - mock_eh.keys = test_keys # pylint: disable=attribute-defined-outside-init + mock_eh.keys = test_keys + + assert not mock_eh.started eh = MockEventHandlerFactory().build(mock_eh) + assert mock_eh.server_connector.keys == test_keys + assert eh.server_connector is mock_eh.server_connector + assert mock_eh.started + assert not mock_eh.last_message + eh.server_connector.simulate_message(test_msg) + assert mock_eh.last_message == test_msg assert not mock_eh.cleaned_up EventHandler.stop_all_instances() assert mock_eh.cleaned_up - assert eh.server_connector.keys == test_keys + + +def test_build_from_simple_object(test_keys, test_msg): + class SimpleMockEventHandler: + # pylint: disable=no-self-use + def handle_event(self, message, server_connector): + raise RuntimeError(message, server_connector) + + mock_eh = SimpleMockEventHandler() + eh = MockEventHandlerFactory().build(mock_eh, keys=test_keys) + + with pytest.raises(RuntimeError) as err: + eh.server_connector.simulate_message(test_msg) + msg, keys = err.args + assert msg == test_msg + assert keys == test_keys def test_build_from_callable(test_keys, test_msg): - class SomeCallable: - def __init__(self): - self.message = None - self.cleaned_up = False - def __call__(self, message, server_connector): - self.message = message - def cleanup(self): - self.cleaned_up = True + mock_eh = MockCallable() - mock_eh = SomeCallable() + assert not mock_eh.started eh = MockEventHandlerFactory().build(mock_eh, keys=test_keys) + assert mock_eh.started + assert mock_eh.server_connector is eh.server_connector assert eh.server_connector.keys == test_keys - assert not mock_eh.message + assert not mock_eh.last_message eh.server_connector.simulate_message(test_msg) - assert mock_eh.message == test_msg + assert mock_eh.last_message == test_msg assert not mock_eh.cleaned_up eh.stop() assert mock_eh.cleaned_up @@ -133,7 +169,7 @@ def test_build_from_lambda(test_keys, test_msg): eh.server_connector.simulate_message(test_msg) -def test_build_raises_if_no_key(): +def test_build_raises_if_no_key(test_keys): eh = MockEventHandler() with pytest.raises(ValueError): MockEventHandlerFactory().build(eh) @@ -145,3 +181,6 @@ def test_build_raises_if_no_key(): with pytest.raises(ValueError): MockEventHandlerFactory().build(lambda msg, sc: None) + + eh.keys = test_keys + MockEventHandlerFactory().build(eh) From 42beafcf04e70e410b993fb00403c76d17ce398f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Fri, 12 Jul 2019 23:14:47 +0200 Subject: [PATCH 06/18] Update dependencies --- requirements.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 610702d..82b480c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,7 @@ PyYAML>=5.0.0,<6.0.0 Jinja2>=2.0.0,<3.0.0 cryptography>=2.0.0,<3.0.0 python-dateutil>=2.0.0,<3.0.0 -SQLAlchemy==1.3.4 +SQLAlchemy>=1.0.0,<2.0.0 +pytest>=5.0.0,<6.0.0 +pylint>=2.0.0,<3.0.0 +rope>=0.0.0,<1.0.0 From de78f489300b54e8374b0e691e4fe4d41f195d83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Fri, 12 Jul 2019 23:25:16 +0200 Subject: [PATCH 07/18] Adjust the whole framework to event handler dependency inversion --- lib/tfw/builtins/__init__.py | 3 - .../directory_snapshotting_event_handler.py | 12 +- lib/tfw/builtins/event_handler.py | 9 -- lib/tfw/builtins/frontend_event_handler.py | 15 ++- lib/tfw/builtins/fsm_aware_event_handler.py | 20 --- .../builtins/fsm_managing_event_handler.py | 12 +- lib/tfw/builtins/ide_event_handler.py | 17 +-- .../builtins/log_monitoring_event_handler.py | 29 +++-- lib/tfw/builtins/pipe_io_event_handler.py | 24 ++-- .../process_managing_event_handler.py | 11 +- .../terminal_commands_event_handler.py | 11 +- lib/tfw/builtins/terminal_event_handler.py | 19 +-- lib/tfw/components/__init__.py | 1 - lib/tfw/components/fsm_updater.py | 2 +- lib/tfw/components/terminal_commands.py | 2 +- lib/tfw/event_handlers/__init__.py | 4 +- lib/tfw/event_handlers/event_handler_base.py | 117 ------------------ .../event_handlers/event_handler_factory.py | 10 +- .../fsm_aware.py | 27 ++-- .../event_handlers/fsm_aware_event_handler.py | 19 +++ lib/tfw/event_handlers/test_event_handler.py | 8 +- lib/tfw/main/__init__.py | 3 + lib/tfw/main/event_handler_factory.py | 8 ++ lib/tfw/main/signal_handling.py | 11 ++ .../tfw_connector.py} | 6 +- lib/tfw/networking/server_connector.py | 23 +++- 26 files changed, 169 insertions(+), 254 deletions(-) delete mode 100644 lib/tfw/builtins/event_handler.py delete mode 100644 lib/tfw/builtins/fsm_aware_event_handler.py delete mode 100644 lib/tfw/event_handlers/event_handler_base.py rename lib/tfw/{components => event_handlers}/fsm_aware.py (50%) create mode 100644 lib/tfw/event_handlers/fsm_aware_event_handler.py create mode 100644 lib/tfw/main/__init__.py create mode 100644 lib/tfw/main/event_handler_factory.py create mode 100644 lib/tfw/main/signal_handling.py rename lib/tfw/{builtins/tfw_server_connector.py => main/tfw_connector.py} (70%) diff --git a/lib/tfw/builtins/__init__.py b/lib/tfw/builtins/__init__.py index d276619..0343fe7 100644 --- a/lib/tfw/builtins/__init__.py +++ b/lib/tfw/builtins/__init__.py @@ -1,7 +1,5 @@ from .directory_snapshotting_event_handler import DirectorySnapshottingEventHandler -from .event_handler import EventHandler from .frontend_event_handler import FrontendEventHandler -from .fsm_aware_event_handler import FSMAwareEventHandler from .fsm_managing_event_handler import FSMManagingEventHandler from .ide_event_handler import IdeEventHandler from .log_monitoring_event_handler import LogMonitoringEventHandler @@ -10,4 +8,3 @@ from .pipe_io_event_handler import TransformerPipeIOEventHandler, CommandEventHa from .process_managing_event_handler import ProcessManagingEventHandler from .terminal_commands_event_handler import TerminalCommandsEventHandler from .terminal_event_handler import TerminalEventHandler -from .tfw_server_connector import TFWServerUplinkConnector, TFWServerConnector diff --git a/lib/tfw/builtins/directory_snapshotting_event_handler.py b/lib/tfw/builtins/directory_snapshotting_event_handler.py index 25986eb..0029f9b 100644 --- a/lib/tfw/builtins/directory_snapshotting_event_handler.py +++ b/lib/tfw/builtins/directory_snapshotting_event_handler.py @@ -10,14 +10,14 @@ from tfw.components.snapshot_provider import SnapshotProvider from tfw.config import TFWENV from tfw.networking import Scope -from .event_handler import EventHandler LOG = logging.getLogger(__name__) -class DirectorySnapshottingEventHandler(EventHandler): - def __init__(self, key, directories, exclude_unix_patterns=None): - super().__init__(key, scope=Scope.WEBSOCKET) +class DirectorySnapshottingEventHandler: + keys = ['snapshot'] + + def __init__(self, directories, exclude_unix_patterns=None): self.snapshot_providers = {} self._exclude_unix_patterns = exclude_unix_patterns self.init_snapshot_providers(directories) @@ -46,11 +46,11 @@ class DirectorySnapshottingEventHandler(EventHandler): makedirs(git_dir, exist_ok=True) return git_dir - def handle_event(self, message): + def handle_event(self, message, server_connector): try: data = message['data'] message['data'] = self.command_handlers[data['command']](data) - self.send_message(message) + server_connector.send_message(message, scope=Scope.WEBSOCKET) except KeyError: LOG.error('IGNORING MESSAGE: Invalid message received: %s', message) diff --git a/lib/tfw/builtins/event_handler.py b/lib/tfw/builtins/event_handler.py deleted file mode 100644 index 9696fe4..0000000 --- a/lib/tfw/builtins/event_handler.py +++ /dev/null @@ -1,9 +0,0 @@ -from tfw.event_handlers import EventHandlerBase - -from .tfw_server_connector import TFWServerConnector - - -class EventHandler(EventHandlerBase): - # pylint: disable=abstract-method - def _build_server_connector(self): - return TFWServerConnector() diff --git a/lib/tfw/builtins/frontend_event_handler.py b/lib/tfw/builtins/frontend_event_handler.py index ba39c27..1fadc5b 100644 --- a/lib/tfw/builtins/frontend_event_handler.py +++ b/lib/tfw/builtins/frontend_event_handler.py @@ -1,16 +1,19 @@ from tfw.networking import Scope from tfw.components import FrontendMessageStorage -from .event_handler import EventHandler +class FrontendEventHandler: + keys = ['message', 'queueMessages', 'dashboard', 'console'] -class FrontendEventHandler(EventHandler): def __init__(self): - frontend_keys = ('message', 'queueMessages', 'dashboard', 'console') - self._frontend_message_storage = FrontendMessageStorage(frontend_keys) - super().__init__((*frontend_keys, 'recover'), scope=Scope.WEBSOCKET) + self.server_connector = None + self.keys = [*type(self).keys, 'recover'] + self._frontend_message_storage = FrontendMessageStorage(type(self).keys) - def handle_event(self, message): + def send_message(self, message): + self.server_connector.send_message(message, scope=Scope.WEBSOCKET) + + def handle_event(self, message, _): self._frontend_message_storage.save_message(message) if message['key'] == 'recover': self.recover_frontend() diff --git a/lib/tfw/builtins/fsm_aware_event_handler.py b/lib/tfw/builtins/fsm_aware_event_handler.py deleted file mode 100644 index d585651..0000000 --- a/lib/tfw/builtins/fsm_aware_event_handler.py +++ /dev/null @@ -1,20 +0,0 @@ -from tfw.components import FSMAware -from tfw.networking import Scope - -from .event_handler import EventHandler - - -class FSMAwareEventHandler(EventHandler, FSMAware): - # pylint: disable=abstract-method - """ - Abstract base class for EventHandlers which automatically - keep track of the state of the TFW FSM. - """ - def __init__(self, key, scope=Scope.ZMQ): - EventHandler.__init__(self, key, scope=scope) - FSMAware.__init__(self) - self.subscribe('fsm_update') - - def dispatch_handling(self, message): - if not self.refresh_on_fsm_update(message): - super().dispatch_handling(message) diff --git a/lib/tfw/builtins/fsm_managing_event_handler.py b/lib/tfw/builtins/fsm_managing_event_handler.py index ccbb7de..dbc568b 100644 --- a/lib/tfw/builtins/fsm_managing_event_handler.py +++ b/lib/tfw/builtins/fsm_managing_event_handler.py @@ -4,12 +4,12 @@ from tfw.crypto import KeyManager, sign_message, verify_message from tfw.networking import Scope from tfw.components import FSMUpdater -from .event_handler import EventHandler LOG = logging.getLogger(__name__) -class FSMManagingEventHandler(EventHandler): +class FSMManagingEventHandler: + keys = ['fsm'] """ EventHandler responsible for managing the state machine of the framework (TFW FSM). @@ -24,8 +24,7 @@ class FSMManagingEventHandler(EventHandler): An 'fsm_update' message is broadcasted after every successful command. """ - def __init__(self, key, fsm_type, require_signature=False): - super().__init__(key, scope=Scope.WEBSOCKET) + def __init__(self, fsm_type, require_signature=False): self.fsm = fsm_type() self._fsm_updater = FSMUpdater(self.fsm) self.auth_key = KeyManager().auth_key @@ -36,15 +35,14 @@ class FSMManagingEventHandler(EventHandler): 'update': self.handle_update } - def handle_event(self, message): + def handle_event(self, message, server_connector): try: message = self.command_handlers[message['data']['command']](message) if message: fsm_update_message = self._fsm_updater.fsm_update sign_message(self.auth_key, message) sign_message(self.auth_key, fsm_update_message) - self.server_connector.send_message(fsm_update_message, Scope.BROADCAST) - self.send_message(message) + server_connector.send_message(fsm_update_message, Scope.BROADCAST) except KeyError: LOG.error('IGNORING MESSAGE: Invalid message received: %s', message) diff --git a/lib/tfw/builtins/ide_event_handler.py b/lib/tfw/builtins/ide_event_handler.py index ab5a7eb..1ec4ebd 100644 --- a/lib/tfw/builtins/ide_event_handler.py +++ b/lib/tfw/builtins/ide_event_handler.py @@ -4,7 +4,6 @@ from tfw.networking import Scope from tfw.components import FileManager from tfw.components.inotify import InotifyObserver -from .event_handler import EventHandler LOG = logging.getLogger(__name__) @@ -32,7 +31,8 @@ BUILD_ARTIFACTS = ( ) -class IdeEventHandler(EventHandler): +class IdeEventHandler: + keys = ['ide'] # pylint: disable=too-many-arguments,anomalous-backslash-in-string """ Event handler implementing the backend of our browser based IDE. @@ -47,7 +47,7 @@ class IdeEventHandler(EventHandler): The API of each command is documented in their respective handler. """ - def __init__(self, key, directory, allowed_directories, selected_file=None, exclude=None): + def __init__(self, directory, allowed_directories, selected_file=None, exclude=None): """ :param key: the key this instance should listen to :param directory: working directory which the EventHandler should serve files from @@ -55,7 +55,7 @@ class IdeEventHandler(EventHandler): :param selected_file: file that is selected by default :param exclude: list of filenames that should not appear between files (for .o, .pyc, etc.) """ - super().__init__(key, scope=Scope.WEBSOCKET) + self.server_connector = None try: self.filemanager = FileManager( allowed_directories=allowed_directories, @@ -84,10 +84,13 @@ class IdeEventHandler(EventHandler): } def _reload_frontend(self, event): # pylint: disable=unused-argument - self.server_connector.send_message({ + self.send_message({ 'key': 'ide', 'data': {'command': 'reload'} - }, Scope.WEBSOCKET) + }) + + def send_message(self, message): + self.server_connector.send_message(message, scope=Scope.WEBSOCKET) def read(self, data): """ @@ -179,7 +182,7 @@ class IdeEventHandler(EventHandler): data['files'] = self.filemanager.files data['directory'] = self.filemanager.workdir - def handle_event(self, message): + def handle_event(self, message, _): try: data = message['data'] message['data'] = self.commands[data['command']](data) diff --git a/lib/tfw/builtins/log_monitoring_event_handler.py b/lib/tfw/builtins/log_monitoring_event_handler.py index eebade5..7e376fc 100644 --- a/lib/tfw/builtins/log_monitoring_event_handler.py +++ b/lib/tfw/builtins/log_monitoring_event_handler.py @@ -1,15 +1,14 @@ import logging from tfw.config import TFWENV -from tfw.networking import Scope from tfw.components import LogInotifyObserver -from .event_handler import EventHandler LOG = logging.getLogger(__name__) -class LogMonitoringEventHandler(EventHandler): +class LogMonitoringEventHandler: + keys = ['logmonitor'] """ Monitors the output of a supervisor process (stdout, stderr) and sends the results to the frontend. @@ -19,23 +18,27 @@ class LogMonitoringEventHandler(EventHandler): The API of each command is documented in their respective handler. """ - def __init__(self, key, process_name, log_tail=0): - super().__init__(key, scope=Scope.WEBSOCKET) + def __init__(self, process_name, log_tail=0): + self.server_connector = None self.process_name = process_name - self._monitor = LogInotifyObserver( - server_connector=self.server_connector, - supervisor_uri=TFWENV.SUPERVISOR_HTTP_URI, - process_name=process_name, - log_tail=log_tail - ) - self._monitor.start() + self._initial_log_tail = log_tail + self._monitor = None self.command_handlers = { 'process_name': self.handle_process_name, 'log_tail': self.handle_log_tail } - def handle_event(self, message): + def start(self): + self._monitor = LogInotifyObserver( + server_connector=self.server_connector, + supervisor_uri=TFWENV.SUPERVISOR_HTTP_URI, + process_name=self.process_name, + log_tail=self._initial_log_tail + ) + self._monitor.start() + + def handle_event(self, message, _): try: data = message['data'] self.command_handlers[data['command']](data) diff --git a/lib/tfw/builtins/pipe_io_event_handler.py b/lib/tfw/builtins/pipe_io_event_handler.py index 96bff90..0a8e02f 100644 --- a/lib/tfw/builtins/pipe_io_event_handler.py +++ b/lib/tfw/builtins/pipe_io_event_handler.py @@ -12,15 +12,16 @@ from contextlib import suppress from tfw.components.pipe_io_server import PipeIOServer, terminate_process_on_failure -from .event_handler import EventHandler LOG = logging.getLogger(__name__) DEFAULT_PERMISSIONS = 0o600 -class PipeIOEventHandlerBase(EventHandler): - def __init__(self, key, in_pipe_path, out_pipe_path, permissions=DEFAULT_PERMISSIONS): - super().__init__(key) +class PipeIOEventHandlerBase: + keys = [''] + + def __init__(self, in_pipe_path, out_pipe_path, permissions=DEFAULT_PERMISSIONS): + self.server_connector = None self.pipe_io = CallbackPipeIOServer( in_pipe_path, out_pipe_path, @@ -50,25 +51,25 @@ class CallbackPipeIOServer(PipeIOServer): class PipeIOEventHandler(PipeIOEventHandlerBase): - def handle_event(self, message): + def handle_event(self, message, _): json_bytes = dumps(message).encode() self.pipe_io.send_message(json_bytes) def handle_pipe_event(self, message_bytes): json = loads(message_bytes) - self.send_message(json) + self.server_connector.send_message(json) class TransformerPipeIOEventHandler(PipeIOEventHandlerBase): # pylint: disable=too-many-arguments def __init__( - self, key, in_pipe_path, out_pipe_path, + self, in_pipe_path, out_pipe_path, transform_in_cmd, transform_out_cmd, permissions=DEFAULT_PERMISSIONS ): self._transform_in = partial(self._transform_message, transform_in_cmd) self._transform_out = partial(self._transform_message, transform_out_cmd) - super().__init__(key, in_pipe_path, out_pipe_path, permissions) + super().__init__(in_pipe_path, out_pipe_path, permissions) @staticmethod def _transform_message(transform_cmd, message): @@ -83,7 +84,7 @@ class TransformerPipeIOEventHandler(PipeIOEventHandlerBase): return proc.stdout raise ValueError(f'Transforming message {message} failed!') - def handle_event(self, message): + def handle_event(self, message, _): json_bytes = dumps(message).encode() transformed_bytes = self._transform_out(json_bytes) if transformed_bytes: @@ -93,13 +94,12 @@ class TransformerPipeIOEventHandler(PipeIOEventHandlerBase): transformed_bytes = self._transform_in(message_bytes) if transformed_bytes: json_message = loads(transformed_bytes) - self.send_message(json_message) + self.server_connector.send_message(json_message) class CommandEventHandler(PipeIOEventHandler): - def __init__(self, key, command, permissions=DEFAULT_PERMISSIONS): + def __init__(self, command, permissions=DEFAULT_PERMISSIONS): super().__init__( - key, self._generate_tempfilename(), self._generate_tempfilename(), permissions diff --git a/lib/tfw/builtins/process_managing_event_handler.py b/lib/tfw/builtins/process_managing_event_handler.py index 2a1f968..fe25ab6 100644 --- a/lib/tfw/builtins/process_managing_event_handler.py +++ b/lib/tfw/builtins/process_managing_event_handler.py @@ -5,12 +5,12 @@ from tfw.config import TFWENV from tfw.networking import Scope from tfw.components import ProcessManager, LogManager -from .event_handler import EventHandler LOG = logging.getLogger(__name__) -class ProcessManagingEventHandler(EventHandler, ProcessManager, LogManager): +class ProcessManagingEventHandler(ProcessManager, LogManager): + keys = ['processmanager'] """ Event handler that can manage processes managed by supervisor. @@ -23,8 +23,7 @@ class ProcessManagingEventHandler(EventHandler, ProcessManager, LogManager): Commands available: start, stop, restart, readlog (the names are as self-documenting as it gets) """ - def __init__(self, key, log_tail=0): - EventHandler.__init__(self, key, scope=Scope.WEBSOCKET) + def __init__(self, log_tail=0): ProcessManager.__init__(self, TFWENV.SUPERVISOR_HTTP_URI) LogManager.__init__(self, TFWENV.SUPERVISOR_HTTP_URI) self.log_tail = log_tail @@ -34,7 +33,7 @@ class ProcessManagingEventHandler(EventHandler, ProcessManager, LogManager): 'restart': self.restart_process } - def handle_event(self, message): + def handle_event(self, message, server_connector): try: data = message['data'] try: @@ -50,6 +49,6 @@ class ProcessManagingEventHandler(EventHandler, ProcessManager, LogManager): data['process_name'], self.log_tail ) - self.send_message(message) + server_connector.send_message(message, scope=Scope.WEBSOCKET) except KeyError: LOG.error('IGNORING MESSAGE: Invalid message received: %s', message) diff --git a/lib/tfw/builtins/terminal_commands_event_handler.py b/lib/tfw/builtins/terminal_commands_event_handler.py index 0385f0b..2bb7399 100644 --- a/lib/tfw/builtins/terminal_commands_event_handler.py +++ b/lib/tfw/builtins/terminal_commands_event_handler.py @@ -1,14 +1,9 @@ from tfw.components import TerminalCommands -from tfw.networking import Scope - -from .event_handler import EventHandler -class TerminalCommandsEventHandler(EventHandler, TerminalCommands): - def __init__(self, key, scope=Scope.ZMQ, bashrc=None): - EventHandler.__init__(self, key, scope) - TerminalCommands.__init__(self, bashrc) +class TerminalCommandsEventHandler(TerminalCommands): + keys = ['history.bash'] - def handle_event(self, message): + def handle_event(self, message, _): command = message['value'] self.callback(command) diff --git a/lib/tfw/builtins/terminal_event_handler.py b/lib/tfw/builtins/terminal_event_handler.py index 1f7bf5f..d02a058 100644 --- a/lib/tfw/builtins/terminal_event_handler.py +++ b/lib/tfw/builtins/terminal_event_handler.py @@ -1,16 +1,15 @@ import logging -from tfw.networking import Scope from tfw.components import BashMonitor, TerminadoMiniServer from tfw.config import TFWENV from tao.config import TAOENV -from .event_handler import EventHandler LOG = logging.getLogger(__name__) -class TerminalEventHandler(EventHandler): +class TerminalEventHandler: + keys = ['shell'] """ Event handler responsible for managing terminal sessions for frontend xterm sessions to connect to. You need to instanciate this in order for frontend @@ -20,13 +19,13 @@ class TerminalEventHandler(EventHandler): a command to be executed. The API of each command is documented in their respective handler. """ - def __init__(self, key): + def __init__(self): """ :param key: key this EventHandler listens to :param monitor: tfw.components.HistoryMonitor instance to read command history from """ - super().__init__(key, scope=Scope.WEBSOCKET) - self._historymonitor = BashMonitor(self.server_connector, TFWENV.HISTFILE) + self.server_connector = None + self._historymonitor = None bash_as_user_cmd = ['sudo', '-u', TAOENV.USER, 'bash'] self.terminado_server = TerminadoMiniServer( @@ -41,18 +40,20 @@ class TerminalEventHandler(EventHandler): 'read': self.read } - self._historymonitor.start() self.terminado_server.listen() + def start(self): + self._historymonitor = BashMonitor(self.server_connector, TFWENV.HISTFILE) + self._historymonitor.start() + @property def historymonitor(self): return self._historymonitor - def handle_event(self, message): + def handle_event(self, message, _): try: data = message['data'] message['data'] = self.commands[data['command']](data) - self.send_message(message) except KeyError: LOG.error('IGNORING MESSAGE: Invalid message received: %s', message) diff --git a/lib/tfw/components/__init__.py b/lib/tfw/components/__init__.py index a1355d7..b44466f 100644 --- a/lib/tfw/components/__init__.py +++ b/lib/tfw/components/__init__.py @@ -1,6 +1,5 @@ from .commands_equal import CommandsEqual from .file_manager import FileManager -from .fsm_aware import FSMAware from .fsm_updater import FSMUpdater from .history_monitor import BashMonitor, GDBMonitor from .log_inotify_observer import LogInotifyObserver diff --git a/lib/tfw/components/fsm_updater.py b/lib/tfw/components/fsm_updater.py index 6bff16a..93f9e7a 100644 --- a/lib/tfw/components/fsm_updater.py +++ b/lib/tfw/components/fsm_updater.py @@ -6,7 +6,7 @@ class FSMUpdater: def fsm_update(self): return { 'key': 'fsm_update', - 'data': self.fsm_update_data + **self.fsm_update_data } @property diff --git a/lib/tfw/components/terminal_commands.py b/lib/tfw/components/terminal_commands.py index adba1b4..d705eb2 100644 --- a/lib/tfw/components/terminal_commands.py +++ b/lib/tfw/components/terminal_commands.py @@ -26,7 +26,7 @@ class TerminalCommands(ABC): You can also use this class to create new commands similarly. """ - def __init__(self, bashrc=None): + def __init__(self, bashrc): self._command_method_regex = r'^command_(.+)$' self.command_implemetations = self._build_command_to_implementation_dict() if bashrc is not None: diff --git a/lib/tfw/event_handlers/__init__.py b/lib/tfw/event_handlers/__init__.py index 7284ec8..8fc4177 100644 --- a/lib/tfw/event_handlers/__init__.py +++ b/lib/tfw/event_handlers/__init__.py @@ -1 +1,3 @@ -from .event_handler_base import EventHandlerBase +from .event_handler_factory import EventHandlerFactoryBase +from .event_handler import EventHandler +from .fsm_aware_event_handler import FSMAwareEventHandler diff --git a/lib/tfw/event_handlers/event_handler_base.py b/lib/tfw/event_handlers/event_handler_base.py deleted file mode 100644 index e56eef5..0000000 --- a/lib/tfw/event_handlers/event_handler_base.py +++ /dev/null @@ -1,117 +0,0 @@ -import logging -from abc import ABC, abstractmethod -from typing import Iterable - -from tfw.networking import Scope - -LOG = logging.getLogger(__name__) - - -class EventHandlerBase(ABC): - """ - Abstract base class for all Python based EventHandlers. Useful implementation template - for other languages. - - Derived classes must implement the handle_event() method - """ - _instances = set() - - def __init__(self, key, scope=Scope.ZMQ): - type(self)._instances.add(self) - self.server_connector = self._build_server_connector() - self.scope = scope - self.keys = [] - if isinstance(key, str): - self.keys.append(key) - elif isinstance(key, Iterable): - self.keys = list(key) - - self.subscribe(*self.keys) - self.server_connector.register_callback(self.event_handler_callback) - - @abstractmethod - def _build_server_connector(self): - raise NotImplementedError() - - def subscribe(self, *keys): - """ - Subscribe this EventHandler to receive events for given keys. - Note that you can subscribe to the same key several times in which - case you will need to unsubscribe multiple times in order to stop - receiving events. - - :param keys: list of keys to subscribe to - """ - for key in keys: - self.server_connector.subscribe(key) - self.keys.append(key) - - def event_handler_callback(self, message): - """ - Callback that is invoked when receiving a message. - Dispatches messages to handler methods and sends - a response back in case the handler returned something. - This is subscribed in __init__(). - """ - if self.check_key(message): - self.dispatch_handling(message) - - def check_key(self, message): - """ - Checks whether the message is intended for this - EventHandler. - - This is necessary because ZMQ handles PUB - SUB - connetions with pattern matching (e.g. someone - subscribed to 'fsm' will receive 'fsm_update' - messages as well. - """ - if '' in self.keys: - return True - return message['key'] in self.keys - - def dispatch_handling(self, message): - """ - Used to dispatch messages to their specific handlers. - - :param message: the message received - :returns: the message to send back - """ - self.handle_event(message) - - def handle_event(self, message): - """ - Abstract method that implements the handling of messages. - - :param message: the message received - :returns: the message to send back - """ - raise NotImplementedError() - - def send_message(self, message): - self.server_connector.send_message(message, self.scope) - - def unsubscribe(self, *keys): - """ - Unsubscribe this eventhandler from the given keys. - - :param keys: list of keys to unsubscribe from - """ - for key in keys: - self.server_connector.unsubscribe(key) - self.keys.remove(key) - - @classmethod - def stop_all_instances(cls): - for instance in cls._instances: - instance.stop() - - def stop(self): - self.server_connector.close() - self.cleanup() - - def cleanup(self): - """ - Perform cleanup actions such as releasing database - connections and stuff like that. - """ diff --git a/lib/tfw/event_handlers/event_handler_factory.py b/lib/tfw/event_handlers/event_handler_factory.py index dc03c46..52f6962 100644 --- a/lib/tfw/event_handlers/event_handler_factory.py +++ b/lib/tfw/event_handlers/event_handler_factory.py @@ -24,13 +24,21 @@ class EventHandlerBuilder: self._event_handler_type = event_handler_type def build(self, server_connector): - server_connector.subscribe(*self._analyzer.keys) event_handler = self._event_handler_type(server_connector) + server_connector.subscribe(*self._try_get_keys(event_handler)) event_handler.handle_event = self._analyzer.handle_event with suppress(AttributeError): event_handler.cleanup = self._analyzer.cleanup return event_handler + def _try_get_keys(self, event_handler): + try: + return self._analyzer.keys + except ValueError: + with suppress(AttributeError): + return event_handler.keys + raise + class EventHandlerAnalyzer: def __init__(self, event_handler, supplied_keys): diff --git a/lib/tfw/components/fsm_aware.py b/lib/tfw/event_handlers/fsm_aware.py similarity index 50% rename from lib/tfw/components/fsm_aware.py rename to lib/tfw/event_handlers/fsm_aware.py index 395a162..76d8d3f 100644 --- a/lib/tfw/components/fsm_aware.py +++ b/lib/tfw/event_handlers/fsm_aware.py @@ -6,6 +6,7 @@ LOG = logging.getLogger(__name__) class FSMAware: + keys = ['fsm_update'] """ Base class for stuff that has to be aware of the framework FSM. This is done by processing 'fsm_update' messages. @@ -16,27 +17,21 @@ class FSMAware: self.fsm_event_log = [] self._auth_key = KeyManager().auth_key - def refresh_on_fsm_update(self, message): - if message['key'] == 'fsm_update' and verify_message(self._auth_key, message): - self._handle_fsm_update(message) - return True - return False + def process_message(self, message): + if message['key'] == 'fsm_update': + if verify_message(self._auth_key, message): + self._handle_fsm_update(message) def _handle_fsm_update(self, message): try: - update_data = message['data'] - new_state = update_data['current_state'] + new_state = message['current_state'] if self.fsm_state != new_state: - self.handle_fsm_step(**update_data) + self.handle_fsm_step(message) self.fsm_state = new_state - self.fsm_in_accepted_state = update_data['in_accepted_state'] - self.fsm_event_log.append(update_data) + self.fsm_in_accepted_state = message['in_accepted_state'] + self.fsm_event_log.append(message) except KeyError: LOG.error('Invalid fsm_update message received!') - def handle_fsm_step(self, **kwargs): - """ - Called in case the TFW FSM has stepped. - - :param kwargs: fsm_update 'data' field - """ + def handle_fsm_step(self, message): + pass diff --git a/lib/tfw/event_handlers/fsm_aware_event_handler.py b/lib/tfw/event_handlers/fsm_aware_event_handler.py new file mode 100644 index 0000000..966d4d4 --- /dev/null +++ b/lib/tfw/event_handlers/fsm_aware_event_handler.py @@ -0,0 +1,19 @@ +from .event_handler import EventHandler +from .fsm_aware import FSMAware + + +class FSMAwareEventHandler(EventHandler, FSMAware): + # pylint: disable=abstract-method + """ + Abstract base class for EventHandlers which automatically + keep track of the state of the TFW FSM. + """ + def __init__(self, server_connector): + EventHandler.__init__(self, server_connector) + FSMAware.__init__(self) + + def _event_callback(self, message): + self.process_message(message) + + def handle_fsm_step(self, message): + self.handle_event(message, self.server_connector) diff --git a/lib/tfw/event_handlers/test_event_handler.py b/lib/tfw/event_handlers/test_event_handler.py index edde537..ae165f3 100644 --- a/lib/tfw/event_handlers/test_event_handler.py +++ b/lib/tfw/event_handlers/test_event_handler.py @@ -174,13 +174,17 @@ def test_build_raises_if_no_key(test_keys): with pytest.raises(ValueError): MockEventHandlerFactory().build(eh) - def test_handle_event(*_): + def handle_event(*_): pass with pytest.raises(ValueError): - MockEventHandlerFactory().build(test_handle_event) + MockEventHandlerFactory().build(handle_event) with pytest.raises(ValueError): MockEventHandlerFactory().build(lambda msg, sc: None) + WithKeysEventHandler = EventHandler + WithKeysEventHandler.keys = test_keys + MockEventHandlerFactory().build(eh, event_handler_type=WithKeysEventHandler) + eh.keys = test_keys MockEventHandlerFactory().build(eh) diff --git a/lib/tfw/main/__init__.py b/lib/tfw/main/__init__.py new file mode 100644 index 0000000..9e1c892 --- /dev/null +++ b/lib/tfw/main/__init__.py @@ -0,0 +1,3 @@ +from .tfw_connector import TFWUplinkConnector, TFWConnector +from .event_handler_factory import EventHandlerFactory +from .signal_handling import setup_signal_handlers diff --git a/lib/tfw/main/event_handler_factory.py b/lib/tfw/main/event_handler_factory.py new file mode 100644 index 0000000..271be8c --- /dev/null +++ b/lib/tfw/main/event_handler_factory.py @@ -0,0 +1,8 @@ +from tfw.event_handlers import EventHandlerFactoryBase + +from .tfw_connector import TFWConnector + + +class EventHandlerFactory(EventHandlerFactoryBase): + def _build_server_connector(self): + return TFWConnector() diff --git a/lib/tfw/main/signal_handling.py b/lib/tfw/main/signal_handling.py new file mode 100644 index 0000000..a8750ef --- /dev/null +++ b/lib/tfw/main/signal_handling.py @@ -0,0 +1,11 @@ +from signal import signal, SIGTERM, SIGINT + +from tfw.event_handlers import EventHandler + + +def setup_signal_handlers(): + def stop(*_): + EventHandler.stop_all_instances() + exit(0) + signal(SIGTERM, stop) + signal(SIGINT, stop) diff --git a/lib/tfw/builtins/tfw_server_connector.py b/lib/tfw/main/tfw_connector.py similarity index 70% rename from lib/tfw/builtins/tfw_server_connector.py rename to lib/tfw/main/tfw_connector.py index 8b8b7c3..2e56996 100644 --- a/lib/tfw/builtins/tfw_server_connector.py +++ b/lib/tfw/main/tfw_connector.py @@ -1,4 +1,4 @@ -from tfw.networking import ServerUplinkConnector, ServerConnector +from tfw.networking import ServerConnector, ServerUplinkConnector from tfw.config import TFWENV @@ -12,12 +12,12 @@ class ConnAddrMixin: return f'tcp://localhost:{TFWENV.PUB_PORT}' -class TFWServerUplinkConnector(ServerUplinkConnector, ConnAddrMixin): +class TFWUplinkConnector(ServerUplinkConnector, ConnAddrMixin): def __init__(self): super().__init__(self.uplink_conn_addr) -class TFWServerConnector(ServerConnector, ConnAddrMixin): +class TFWConnector(ServerConnector, ConnAddrMixin): def __init__(self): super().__init__( self.downlink_conn_addr, diff --git a/lib/tfw/networking/server_connector.py b/lib/tfw/networking/server_connector.py index da407ac..0ab1644 100644 --- a/lib/tfw/networking/server_connector.py +++ b/lib/tfw/networking/server_connector.py @@ -1,5 +1,4 @@ import logging -from functools import partial import zmq from zmq.eventloop.zmqstream import ZMQStream @@ -12,17 +11,31 @@ LOG = logging.getLogger(__name__) class ServerDownlinkConnector: def __init__(self, connect_addr): + self.keys = [] + self._on_recv_callback = None self._zmq_sub_socket = zmq.Context.instance().socket(zmq.SUB) self._zmq_sub_socket.setsockopt(zmq.RCVHWM, 0) self._zmq_sub_socket.connect(connect_addr) self._zmq_sub_stream = ZMQStream(self._zmq_sub_socket) - self.subscribe = partial(self._zmq_sub_socket.setsockopt_string, zmq.SUBSCRIBE) - self.unsubscribe = partial(self._zmq_sub_socket.setsockopt_string, zmq.UNSUBSCRIBE) + def subscribe(self, *keys): + for key in keys: + self._zmq_sub_socket.setsockopt_string(zmq.SUBSCRIBE, key) + self.keys.append(key) + + def unsubscribe(self, *keys): + for key in keys: + self._zmq_sub_socket.setsockopt_string(zmq.UNSUBSCRIBE, key) + self.keys.remove(key) def register_callback(self, callback): - callback = with_deserialize_tfw_msg(callback) - self._zmq_sub_stream.on_recv(callback) + self._on_recv_callback = callback + self._zmq_sub_stream.on_recv(with_deserialize_tfw_msg(self._on_recv)) + + def _on_recv(self, message): + key = message['key'] + if key in self.keys or '' in self.keys: + self._on_recv_callback(message) def close(self): self._zmq_sub_stream.close() From 026db9ea84c5f64478d958849f478ac518af6ee0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Fri, 12 Jul 2019 23:32:15 +0200 Subject: [PATCH 08/18] Avoid duplicate filename (EventHandlerFactory) --- lib/tfw/event_handlers/__init__.py | 2 +- .../{event_handler_factory.py => event_handler_factory_base.py} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename lib/tfw/event_handlers/{event_handler_factory.py => event_handler_factory_base.py} (100%) diff --git a/lib/tfw/event_handlers/__init__.py b/lib/tfw/event_handlers/__init__.py index 8fc4177..2a33065 100644 --- a/lib/tfw/event_handlers/__init__.py +++ b/lib/tfw/event_handlers/__init__.py @@ -1,3 +1,3 @@ -from .event_handler_factory import EventHandlerFactoryBase +from .event_handler_factory_base import EventHandlerFactoryBase from .event_handler import EventHandler from .fsm_aware_event_handler import FSMAwareEventHandler diff --git a/lib/tfw/event_handlers/event_handler_factory.py b/lib/tfw/event_handlers/event_handler_factory_base.py similarity index 100% rename from lib/tfw/event_handlers/event_handler_factory.py rename to lib/tfw/event_handlers/event_handler_factory_base.py From adf2672cd425d2f1f5f72caaf7cebfabd5b4bfc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Fri, 12 Jul 2019 23:38:18 +0200 Subject: [PATCH 09/18] Add forgotten dateutil dependency --- requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements.txt b/requirements.txt index 82b480c..3c34b45 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,6 +8,7 @@ Jinja2>=2.0.0,<3.0.0 cryptography>=2.0.0,<3.0.0 python-dateutil>=2.0.0,<3.0.0 SQLAlchemy>=1.0.0,<2.0.0 +python-dateutil>=2.0.0,<3.0.0 pytest>=5.0.0,<6.0.0 pylint>=2.0.0,<3.0.0 rope>=0.0.0,<1.0.0 From 45a9a753b25c5f21021e7972c8dd10add18307ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Mon, 15 Jul 2019 11:09:43 +0200 Subject: [PATCH 10/18] Fix test_event_handler --- lib/tfw/event_handlers/test_event_handler.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tfw/event_handlers/test_event_handler.py b/lib/tfw/event_handlers/test_event_handler.py index ae165f3..049bb78 100644 --- a/lib/tfw/event_handlers/test_event_handler.py +++ b/lib/tfw/event_handlers/test_event_handler.py @@ -4,7 +4,7 @@ from random import randint import pytest -from .event_handler_factory import EventHandlerFactoryBase +from .event_handler_factory_base import EventHandlerFactoryBase from .event_handler import EventHandler @@ -71,7 +71,7 @@ def test_msg(): @pytest.fixture def test_keys(): yield [ - token_urlsafe(randint(2, 8)) + token_urlsafe(randint(2, 8)) for _ in range(randint(16, 32)) ] From 9725f805edf0803be50d03ba4e9f72e07a2cf111 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Mon, 15 Jul 2019 11:09:57 +0200 Subject: [PATCH 11/18] Silence unjust pylint warnings --- lib/tfw/server/zmq_websocket_router.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tfw/server/zmq_websocket_router.py b/lib/tfw/server/zmq_websocket_router.py index cb19c33..b7adf16 100644 --- a/lib/tfw/server/zmq_websocket_router.py +++ b/lib/tfw/server/zmq_websocket_router.py @@ -9,10 +9,10 @@ LOG = logging.getLogger(__name__) class ZMQWebSocketRouter(WebSocketHandler): - # pylint: disable=abstract-method + # pylint: disable=abstract-method,attribute-defined-outside-init instances = set() - def initialize(self, **kwargs): # pylint: disable=arguments-differ + def initialize(self, **kwargs): self.event_handler_connector = kwargs['event_handler_connector'] self.tfw_router = TFWRouter(self.send_to_zmq, self.send_to_websockets) From ae69a094c7459ec9963d45aa19592e30287accff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Tue, 23 Jul 2019 11:47:59 +0200 Subject: [PATCH 12/18] Improve names in EventHandlerFactoryBase to improve readability --- .../event_handler_factory_base.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/tfw/event_handlers/event_handler_factory_base.py b/lib/tfw/event_handlers/event_handler_factory_base.py index 52f6962..4c4adcd 100644 --- a/lib/tfw/event_handlers/event_handler_factory_base.py +++ b/lib/tfw/event_handlers/event_handler_factory_base.py @@ -4,15 +4,15 @@ from .event_handler import EventHandler class EventHandlerFactoryBase: - def build(self, event_handler, *, keys=None, event_handler_type=EventHandler): - builder = EventHandlerBuilder(event_handler, keys, event_handler_type) + def build(self, handler_stub, *, keys=None, event_handler_type=EventHandler): + builder = EventHandlerBuilder(handler_stub, keys, event_handler_type) server_connector = self._build_server_connector() - real_event_handler = builder.build(server_connector) - event_handler.server_connector = server_connector + event_handler = builder.build(server_connector) + handler_stub.server_connector = server_connector with suppress(AttributeError): - event_handler.start() - real_event_handler.start() - return real_event_handler + handler_stub.start() + event_handler.start() + return event_handler def _build_server_connector(self): raise NotImplementedError() @@ -20,7 +20,7 @@ class EventHandlerFactoryBase: class EventHandlerBuilder: def __init__(self, event_handler, supplied_keys, event_handler_type): - self._analyzer = EventHandlerAnalyzer(event_handler, supplied_keys) + self._analyzer = HandlerStubAnalyzer(event_handler, supplied_keys) self._event_handler_type = event_handler_type def build(self, server_connector): @@ -40,7 +40,7 @@ class EventHandlerBuilder: raise -class EventHandlerAnalyzer: +class HandlerStubAnalyzer: def __init__(self, event_handler, supplied_keys): self._event_handler = event_handler self._supplied_keys = supplied_keys From c6e01d294df346e16edd6029a0d78de8fdff76eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Tue, 23 Jul 2019 15:32:50 +0200 Subject: [PATCH 13/18] Inject TFWENV dependencies to builtins --- .../directory_snapshotting_event_handler.py | 9 ++++----- lib/tfw/builtins/fsm_managing_event_handler.py | 2 +- lib/tfw/builtins/ide_event_handler.py | 2 +- lib/tfw/builtins/log_monitoring_event_handler.py | 6 +++--- lib/tfw/builtins/process_managing_event_handler.py | 7 +++---- lib/tfw/builtins/terminal_event_handler.py | 13 ++++++------- 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/lib/tfw/builtins/directory_snapshotting_event_handler.py b/lib/tfw/builtins/directory_snapshotting_event_handler.py index 0029f9b..91aff92 100644 --- a/lib/tfw/builtins/directory_snapshotting_event_handler.py +++ b/lib/tfw/builtins/directory_snapshotting_event_handler.py @@ -7,7 +7,6 @@ from datetime import datetime from dateutil import parser as dateparser from tfw.components.snapshot_provider import SnapshotProvider -from tfw.config import TFWENV from tfw.networking import Scope @@ -17,7 +16,8 @@ LOG = logging.getLogger(__name__) class DirectorySnapshottingEventHandler: keys = ['snapshot'] - def __init__(self, directories, exclude_unix_patterns=None): + def __init__(self, *, directories, snapshots_dir, exclude_unix_patterns=None): + self._snapshots_dir = snapshots_dir self.snapshot_providers = {} self._exclude_unix_patterns = exclude_unix_patterns self.init_snapshot_providers(directories) @@ -37,10 +37,9 @@ class DirectorySnapshottingEventHandler: self._exclude_unix_patterns ) - @staticmethod - def init_git_dir(index, directory): + def init_git_dir(self, index, directory): git_dir = joinpath( - TFWENV.SNAPSHOTS_DIR, + self._snapshots_dir, f'{basename(directory)}-{index}' ) makedirs(git_dir, exist_ok=True) diff --git a/lib/tfw/builtins/fsm_managing_event_handler.py b/lib/tfw/builtins/fsm_managing_event_handler.py index dbc568b..2bf7fa2 100644 --- a/lib/tfw/builtins/fsm_managing_event_handler.py +++ b/lib/tfw/builtins/fsm_managing_event_handler.py @@ -24,7 +24,7 @@ class FSMManagingEventHandler: An 'fsm_update' message is broadcasted after every successful command. """ - def __init__(self, fsm_type, require_signature=False): + def __init__(self, *, fsm_type, require_signature=False): self.fsm = fsm_type() self._fsm_updater = FSMUpdater(self.fsm) self.auth_key = KeyManager().auth_key diff --git a/lib/tfw/builtins/ide_event_handler.py b/lib/tfw/builtins/ide_event_handler.py index 1ec4ebd..6cff1f4 100644 --- a/lib/tfw/builtins/ide_event_handler.py +++ b/lib/tfw/builtins/ide_event_handler.py @@ -47,7 +47,7 @@ class IdeEventHandler: The API of each command is documented in their respective handler. """ - def __init__(self, directory, allowed_directories, selected_file=None, exclude=None): + def __init__(self, *, directory, allowed_directories, selected_file=None, exclude=None): """ :param key: the key this instance should listen to :param directory: working directory which the EventHandler should serve files from diff --git a/lib/tfw/builtins/log_monitoring_event_handler.py b/lib/tfw/builtins/log_monitoring_event_handler.py index 7e376fc..54927eb 100644 --- a/lib/tfw/builtins/log_monitoring_event_handler.py +++ b/lib/tfw/builtins/log_monitoring_event_handler.py @@ -1,6 +1,5 @@ import logging -from tfw.config import TFWENV from tfw.components import LogInotifyObserver @@ -18,9 +17,10 @@ class LogMonitoringEventHandler: The API of each command is documented in their respective handler. """ - def __init__(self, process_name, log_tail=0): + def __init__(self, *, process_name, supervisor_uri, log_tail=0): self.server_connector = None self.process_name = process_name + self._supervisor_uri = supervisor_uri self._initial_log_tail = log_tail self._monitor = None @@ -32,7 +32,7 @@ class LogMonitoringEventHandler: def start(self): self._monitor = LogInotifyObserver( server_connector=self.server_connector, - supervisor_uri=TFWENV.SUPERVISOR_HTTP_URI, + supervisor_uri=self._supervisor_uri, process_name=self.process_name, log_tail=self._initial_log_tail ) diff --git a/lib/tfw/builtins/process_managing_event_handler.py b/lib/tfw/builtins/process_managing_event_handler.py index fe25ab6..41eb114 100644 --- a/lib/tfw/builtins/process_managing_event_handler.py +++ b/lib/tfw/builtins/process_managing_event_handler.py @@ -1,7 +1,6 @@ import logging from xmlrpc.client import Fault as SupervisorFault -from tfw.config import TFWENV from tfw.networking import Scope from tfw.components import ProcessManager, LogManager @@ -23,9 +22,9 @@ class ProcessManagingEventHandler(ProcessManager, LogManager): Commands available: start, stop, restart, readlog (the names are as self-documenting as it gets) """ - def __init__(self, log_tail=0): - ProcessManager.__init__(self, TFWENV.SUPERVISOR_HTTP_URI) - LogManager.__init__(self, TFWENV.SUPERVISOR_HTTP_URI) + def __init__(self, *, supervisor_uri, log_tail=0): + ProcessManager.__init__(self, supervisor_uri) + LogManager.__init__(self, supervisor_uri) self.log_tail = log_tail self.commands = { 'start': self.start_process, diff --git a/lib/tfw/builtins/terminal_event_handler.py b/lib/tfw/builtins/terminal_event_handler.py index d02a058..6cee755 100644 --- a/lib/tfw/builtins/terminal_event_handler.py +++ b/lib/tfw/builtins/terminal_event_handler.py @@ -1,8 +1,6 @@ import logging from tfw.components import BashMonitor, TerminadoMiniServer -from tfw.config import TFWENV -from tao.config import TAOENV LOG = logging.getLogger(__name__) @@ -19,19 +17,20 @@ class TerminalEventHandler: a command to be executed. The API of each command is documented in their respective handler. """ - def __init__(self): + def __init__(self, *, port, user, workind_directory, histfile): """ :param key: key this EventHandler listens to :param monitor: tfw.components.HistoryMonitor instance to read command history from """ self.server_connector = None + self._histfile = histfile self._historymonitor = None - bash_as_user_cmd = ['sudo', '-u', TAOENV.USER, 'bash'] + bash_as_user_cmd = ['sudo', '-u', user, 'bash'] self.terminado_server = TerminadoMiniServer( '/terminal', - TFWENV.TERMINADO_PORT, - TFWENV.TERMINADO_WD, + port, + workind_directory, bash_as_user_cmd ) @@ -43,7 +42,7 @@ class TerminalEventHandler: self.terminado_server.listen() def start(self): - self._historymonitor = BashMonitor(self.server_connector, TFWENV.HISTFILE) + self._historymonitor = BashMonitor(self.server_connector, self._histfile) self._historymonitor.start() @property From a23224acedab87697d9bd1fef5a8213001baba71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Wed, 24 Jul 2019 15:17:16 +0200 Subject: [PATCH 14/18] Rework whole package structure (improved dependency handling) --- lib/envvars/__init__.py | 2 +- lib/tfw/builtins/__init__.py | 10 ---------- lib/tfw/components/__init__.py | 11 ----------- lib/tfw/components/frontend/__init__.py | 2 ++ .../frontend/frontend_handler.py} | 7 ++++--- lib/tfw/components/{ => frontend}/message_sender.py | 0 lib/tfw/components/{ => frontend}/message_storage.py | 0 lib/tfw/components/fsm/__init__.py | 1 + .../fsm/fsm_handler.py} | 9 +++++---- lib/tfw/components/{ => fsm}/fsm_updater.py | 0 lib/tfw/components/ide/__init__.py | 1 + lib/tfw/components/{ => ide}/file_manager/__init__.py | 0 .../components/{ => ide}/file_manager/file_manager.py | 0 .../{ => ide}/file_manager/test_file_manager.py | 0 .../ide/ide_handler.py} | 9 +++++---- lib/tfw/components/pipe_io/__init__.py | 1 + .../pipe_io/pipe_io_handler.py} | 10 +++++----- .../{ => pipe_io}/pipe_io_server/__init__.py | 0 .../components/{ => pipe_io}/pipe_io_server/deque.py | 0 .../components/{ => pipe_io}/pipe_io_server/pipe.py | 0 .../{ => pipe_io}/pipe_io_server/pipe_io_server.py | 0 .../pipe_io_server/pipe_reader_thread.py | 0 .../pipe_io_server/pipe_writer_thread.py | 0 .../pipe_io_server/terminate_process_on_failure.py | 0 lib/tfw/components/process_management/__init__.py | 2 ++ .../{ => process_management}/log_inotify_observer.py | 10 +++++----- .../process_management/process_handler.py} | 9 +++++---- .../process_management/process_log_handler.py} | 4 ++-- .../components/{ => process_management}/supervisor.py | 2 +- lib/tfw/components/snapshots/__init__.py | 1 + .../snapshots/snapshot_handler.py} | 7 ++++--- .../components/{ => snapshots}/snapshot_provider.py | 0 lib/tfw/components/terminal/__init__.py | 3 +++ lib/tfw/components/{ => terminal}/commands_equal.py | 2 +- lib/tfw/components/{ => terminal}/history_monitor.py | 2 +- .../{ => terminal}/terminado_mini_server.py | 0 .../components/{ => terminal}/terminal_commands.py | 0 .../terminal/terminal_commands_handler.py} | 4 ++-- .../terminal/terminal_handler.py} | 5 +++-- lib/tfw/event_handlers.py | 2 ++ lib/tfw/fsm/fsm_base.py | 2 +- lib/tfw/fsm/linear_fsm.py | 2 +- lib/tfw/fsm/yaml_fsm.py | 2 +- lib/tfw/{decorators => internals}/__init__.py | 0 lib/tfw/{mixins => internals}/callback_mixin.py | 2 +- lib/tfw/{ => internals}/crypto.py | 4 ++-- .../event_handling}/__init__.py | 0 .../event_handling}/event_handler.py | 0 .../event_handling}/event_handler_factory_base.py | 0 .../event_handling}/fsm_aware.py | 2 +- .../event_handling}/fsm_aware_event_handler.py | 0 .../event_handling}/test_event_handler.py | 0 lib/tfw/{components => internals}/inotify/__init__.py | 0 lib/tfw/{components => internals}/inotify/inotify.py | 0 .../{components => internals}/inotify/test_inotify.py | 0 .../lazy_property.py => internals/lazy.py} | 0 lib/tfw/{ => internals}/networking/__init__.py | 0 .../networking/event_handler_connector.py | 0 lib/tfw/{ => internals}/networking/scope.py | 0 lib/tfw/{ => internals}/networking/serialization.py | 0 .../{ => internals}/networking/server_connector.py | 0 lib/tfw/internals/server/__init__.py | 1 + .../{ => internals}/server/zmq_websocket_router.py | 2 +- lib/tfw/logging.py | 2 +- lib/tfw/main/__init__.py | 1 + lib/tfw/main/event_handler_factory.py | 2 +- lib/tfw/main/signal_handling.py | 2 +- lib/tfw/main/tfw_connector.py | 2 +- lib/tfw/{server => main}/tfw_server.py | 4 ++-- lib/tfw/mixins/__init__.py | 0 lib/tfw/server/__init__.py | 1 - supervisor/tfw_server.py | 2 +- 72 files changed, 74 insertions(+), 75 deletions(-) delete mode 100644 lib/tfw/builtins/__init__.py create mode 100644 lib/tfw/components/frontend/__init__.py rename lib/tfw/{builtins/frontend_event_handler.py => components/frontend/frontend_handler.py} (85%) rename lib/tfw/components/{ => frontend}/message_sender.py (100%) rename lib/tfw/components/{ => frontend}/message_storage.py (100%) create mode 100644 lib/tfw/components/fsm/__init__.py rename lib/tfw/{builtins/fsm_managing_event_handler.py => components/fsm/fsm_handler.py} (92%) rename lib/tfw/components/{ => fsm}/fsm_updater.py (100%) create mode 100644 lib/tfw/components/ide/__init__.py rename lib/tfw/components/{ => ide}/file_manager/__init__.py (100%) rename lib/tfw/components/{ => ide}/file_manager/file_manager.py (100%) rename lib/tfw/components/{ => ide}/file_manager/test_file_manager.py (100%) rename lib/tfw/{builtins/ide_event_handler.py => components/ide/ide_handler.py} (97%) create mode 100644 lib/tfw/components/pipe_io/__init__.py rename lib/tfw/{builtins/pipe_io_event_handler.py => components/pipe_io/pipe_io_handler.py} (94%) rename lib/tfw/components/{ => pipe_io}/pipe_io_server/__init__.py (100%) rename lib/tfw/components/{ => pipe_io}/pipe_io_server/deque.py (100%) rename lib/tfw/components/{ => pipe_io}/pipe_io_server/pipe.py (100%) rename lib/tfw/components/{ => pipe_io}/pipe_io_server/pipe_io_server.py (100%) rename lib/tfw/components/{ => pipe_io}/pipe_io_server/pipe_reader_thread.py (100%) rename lib/tfw/components/{ => pipe_io}/pipe_io_server/pipe_writer_thread.py (100%) rename lib/tfw/components/{ => pipe_io}/pipe_io_server/terminate_process_on_failure.py (100%) create mode 100644 lib/tfw/components/process_management/__init__.py rename lib/tfw/components/{ => process_management}/log_inotify_observer.py (84%) rename lib/tfw/{builtins/process_managing_event_handler.py => components/process_management/process_handler.py} (88%) rename lib/tfw/{builtins/log_monitoring_event_handler.py => components/process_management/process_log_handler.py} (96%) rename lib/tfw/components/{ => process_management}/supervisor.py (96%) create mode 100644 lib/tfw/components/snapshots/__init__.py rename lib/tfw/{builtins/directory_snapshotting_event_handler.py => components/snapshots/snapshot_handler.py} (95%) rename lib/tfw/components/{ => snapshots}/snapshot_provider.py (100%) create mode 100644 lib/tfw/components/terminal/__init__.py rename lib/tfw/components/{ => terminal}/commands_equal.py (98%) rename lib/tfw/components/{ => terminal}/history_monitor.py (98%) rename lib/tfw/components/{ => terminal}/terminado_mini_server.py (100%) rename lib/tfw/components/{ => terminal}/terminal_commands.py (100%) rename lib/tfw/{builtins/terminal_commands_event_handler.py => components/terminal/terminal_commands_handler.py} (58%) rename lib/tfw/{builtins/terminal_event_handler.py => components/terminal/terminal_handler.py} (95%) create mode 100644 lib/tfw/event_handlers.py rename lib/tfw/{decorators => internals}/__init__.py (100%) rename lib/tfw/{mixins => internals}/callback_mixin.py (95%) rename lib/tfw/{ => internals}/crypto.py (96%) rename lib/tfw/{event_handlers => internals/event_handling}/__init__.py (100%) rename lib/tfw/{event_handlers => internals/event_handling}/event_handler.py (100%) rename lib/tfw/{event_handlers => internals/event_handling}/event_handler_factory_base.py (100%) rename lib/tfw/{event_handlers => internals/event_handling}/fsm_aware.py (94%) rename lib/tfw/{event_handlers => internals/event_handling}/fsm_aware_event_handler.py (100%) rename lib/tfw/{event_handlers => internals/event_handling}/test_event_handler.py (100%) rename lib/tfw/{components => internals}/inotify/__init__.py (100%) rename lib/tfw/{components => internals}/inotify/inotify.py (100%) rename lib/tfw/{components => internals}/inotify/test_inotify.py (100%) rename lib/tfw/{decorators/lazy_property.py => internals/lazy.py} (100%) rename lib/tfw/{ => internals}/networking/__init__.py (100%) rename lib/tfw/{ => internals}/networking/event_handler_connector.py (100%) rename lib/tfw/{ => internals}/networking/scope.py (100%) rename lib/tfw/{ => internals}/networking/serialization.py (100%) rename lib/tfw/{ => internals}/networking/server_connector.py (100%) create mode 100644 lib/tfw/internals/server/__init__.py rename lib/tfw/{ => internals}/server/zmq_websocket_router.py (97%) rename lib/tfw/{server => main}/tfw_server.py (88%) delete mode 100644 lib/tfw/mixins/__init__.py delete mode 100644 lib/tfw/server/__init__.py diff --git a/lib/envvars/__init__.py b/lib/envvars/__init__.py index a96ed9f..db9a3df 100644 --- a/lib/envvars/__init__.py +++ b/lib/envvars/__init__.py @@ -1,7 +1,7 @@ from collections import namedtuple from os import environ -from tfw.decorators.lazy_property import lazy_property +from tfw.internals.lazy import lazy_property class LazyEnvironment: diff --git a/lib/tfw/builtins/__init__.py b/lib/tfw/builtins/__init__.py deleted file mode 100644 index 0343fe7..0000000 --- a/lib/tfw/builtins/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from .directory_snapshotting_event_handler import DirectorySnapshottingEventHandler -from .frontend_event_handler import FrontendEventHandler -from .fsm_managing_event_handler import FSMManagingEventHandler -from .ide_event_handler import IdeEventHandler -from .log_monitoring_event_handler import LogMonitoringEventHandler -from .pipe_io_event_handler import PipeIOEventHandlerBase, PipeIOEventHandler -from .pipe_io_event_handler import TransformerPipeIOEventHandler, CommandEventHandler -from .process_managing_event_handler import ProcessManagingEventHandler -from .terminal_commands_event_handler import TerminalCommandsEventHandler -from .terminal_event_handler import TerminalEventHandler diff --git a/lib/tfw/components/__init__.py b/lib/tfw/components/__init__.py index b44466f..e69de29 100644 --- a/lib/tfw/components/__init__.py +++ b/lib/tfw/components/__init__.py @@ -1,11 +0,0 @@ -from .commands_equal import CommandsEqual -from .file_manager import FileManager -from .fsm_updater import FSMUpdater -from .history_monitor import BashMonitor, GDBMonitor -from .log_inotify_observer import LogInotifyObserver -from .message_sender import MessageSender -from .message_storage import FrontendMessageStorage -from .snapshot_provider import SnapshotProvider -from .supervisor import ProcessManager, LogManager -from .terminado_mini_server import TerminadoMiniServer -from .terminal_commands import TerminalCommands diff --git a/lib/tfw/components/frontend/__init__.py b/lib/tfw/components/frontend/__init__.py new file mode 100644 index 0000000..3e0b871 --- /dev/null +++ b/lib/tfw/components/frontend/__init__.py @@ -0,0 +1,2 @@ +from .frontend_handler import FrontendHandler +from .message_sender import MessageSender diff --git a/lib/tfw/builtins/frontend_event_handler.py b/lib/tfw/components/frontend/frontend_handler.py similarity index 85% rename from lib/tfw/builtins/frontend_event_handler.py rename to lib/tfw/components/frontend/frontend_handler.py index 1fadc5b..b5e7c8b 100644 --- a/lib/tfw/builtins/frontend_event_handler.py +++ b/lib/tfw/components/frontend/frontend_handler.py @@ -1,8 +1,9 @@ -from tfw.networking import Scope -from tfw.components import FrontendMessageStorage +from tfw.internals.networking import Scope + +from .message_storage import FrontendMessageStorage -class FrontendEventHandler: +class FrontendHandler: keys = ['message', 'queueMessages', 'dashboard', 'console'] def __init__(self): diff --git a/lib/tfw/components/message_sender.py b/lib/tfw/components/frontend/message_sender.py similarity index 100% rename from lib/tfw/components/message_sender.py rename to lib/tfw/components/frontend/message_sender.py diff --git a/lib/tfw/components/message_storage.py b/lib/tfw/components/frontend/message_storage.py similarity index 100% rename from lib/tfw/components/message_storage.py rename to lib/tfw/components/frontend/message_storage.py diff --git a/lib/tfw/components/fsm/__init__.py b/lib/tfw/components/fsm/__init__.py new file mode 100644 index 0000000..5e8f625 --- /dev/null +++ b/lib/tfw/components/fsm/__init__.py @@ -0,0 +1 @@ +from .fsm_handler import FSMHandler diff --git a/lib/tfw/builtins/fsm_managing_event_handler.py b/lib/tfw/components/fsm/fsm_handler.py similarity index 92% rename from lib/tfw/builtins/fsm_managing_event_handler.py rename to lib/tfw/components/fsm/fsm_handler.py index 2bf7fa2..2dc163e 100644 --- a/lib/tfw/builtins/fsm_managing_event_handler.py +++ b/lib/tfw/components/fsm/fsm_handler.py @@ -1,14 +1,15 @@ import logging -from tfw.crypto import KeyManager, sign_message, verify_message -from tfw.networking import Scope -from tfw.components import FSMUpdater +from tfw.internals.crypto import KeyManager, sign_message, verify_message +from tfw.internals.networking import Scope + +from .fsm_updater import FSMUpdater LOG = logging.getLogger(__name__) -class FSMManagingEventHandler: +class FSMHandler: keys = ['fsm'] """ EventHandler responsible for managing the state machine of diff --git a/lib/tfw/components/fsm_updater.py b/lib/tfw/components/fsm/fsm_updater.py similarity index 100% rename from lib/tfw/components/fsm_updater.py rename to lib/tfw/components/fsm/fsm_updater.py diff --git a/lib/tfw/components/ide/__init__.py b/lib/tfw/components/ide/__init__.py new file mode 100644 index 0000000..2d4ae3e --- /dev/null +++ b/lib/tfw/components/ide/__init__.py @@ -0,0 +1 @@ +from .ide_handler import IdeHandler diff --git a/lib/tfw/components/file_manager/__init__.py b/lib/tfw/components/ide/file_manager/__init__.py similarity index 100% rename from lib/tfw/components/file_manager/__init__.py rename to lib/tfw/components/ide/file_manager/__init__.py diff --git a/lib/tfw/components/file_manager/file_manager.py b/lib/tfw/components/ide/file_manager/file_manager.py similarity index 100% rename from lib/tfw/components/file_manager/file_manager.py rename to lib/tfw/components/ide/file_manager/file_manager.py diff --git a/lib/tfw/components/file_manager/test_file_manager.py b/lib/tfw/components/ide/file_manager/test_file_manager.py similarity index 100% rename from lib/tfw/components/file_manager/test_file_manager.py rename to lib/tfw/components/ide/file_manager/test_file_manager.py diff --git a/lib/tfw/builtins/ide_event_handler.py b/lib/tfw/components/ide/ide_handler.py similarity index 97% rename from lib/tfw/builtins/ide_event_handler.py rename to lib/tfw/components/ide/ide_handler.py index 6cff1f4..225b80c 100644 --- a/lib/tfw/builtins/ide_event_handler.py +++ b/lib/tfw/components/ide/ide_handler.py @@ -1,8 +1,9 @@ import logging -from tfw.networking import Scope -from tfw.components import FileManager -from tfw.components.inotify import InotifyObserver +from tfw.internals.networking import Scope +from tfw.internals.inotify import InotifyObserver + +from .file_manager import FileManager LOG = logging.getLogger(__name__) @@ -31,7 +32,7 @@ BUILD_ARTIFACTS = ( ) -class IdeEventHandler: +class IdeHandler: keys = ['ide'] # pylint: disable=too-many-arguments,anomalous-backslash-in-string """ diff --git a/lib/tfw/components/pipe_io/__init__.py b/lib/tfw/components/pipe_io/__init__.py new file mode 100644 index 0000000..43a5b98 --- /dev/null +++ b/lib/tfw/components/pipe_io/__init__.py @@ -0,0 +1 @@ +from .pipe_io_handler import PipeIOHandler, PipeIOHandlerBase, TransformerPipeIOHandler, CommandHandler diff --git a/lib/tfw/builtins/pipe_io_event_handler.py b/lib/tfw/components/pipe_io/pipe_io_handler.py similarity index 94% rename from lib/tfw/builtins/pipe_io_event_handler.py rename to lib/tfw/components/pipe_io/pipe_io_handler.py index 0a8e02f..4f6a850 100644 --- a/lib/tfw/builtins/pipe_io_event_handler.py +++ b/lib/tfw/components/pipe_io/pipe_io_handler.py @@ -10,14 +10,14 @@ from secrets import token_urlsafe from threading import Thread from contextlib import suppress -from tfw.components.pipe_io_server import PipeIOServer, terminate_process_on_failure +from .pipe_io_server import PipeIOServer, terminate_process_on_failure LOG = logging.getLogger(__name__) DEFAULT_PERMISSIONS = 0o600 -class PipeIOEventHandlerBase: +class PipeIOHandlerBase: keys = [''] def __init__(self, in_pipe_path, out_pipe_path, permissions=DEFAULT_PERMISSIONS): @@ -50,7 +50,7 @@ class CallbackPipeIOServer(PipeIOServer): LOG.exception('Failed to handle message %s from pipe %s!', message, self.in_pipe) -class PipeIOEventHandler(PipeIOEventHandlerBase): +class PipeIOHandler(PipeIOHandlerBase): def handle_event(self, message, _): json_bytes = dumps(message).encode() self.pipe_io.send_message(json_bytes) @@ -60,7 +60,7 @@ class PipeIOEventHandler(PipeIOEventHandlerBase): self.server_connector.send_message(json) -class TransformerPipeIOEventHandler(PipeIOEventHandlerBase): +class TransformerPipeIOHandler(PipeIOHandlerBase): # pylint: disable=too-many-arguments def __init__( self, in_pipe_path, out_pipe_path, @@ -97,7 +97,7 @@ class TransformerPipeIOEventHandler(PipeIOEventHandlerBase): self.server_connector.send_message(json_message) -class CommandEventHandler(PipeIOEventHandler): +class CommandHandler(PipeIOHandler): def __init__(self, command, permissions=DEFAULT_PERMISSIONS): super().__init__( self._generate_tempfilename(), diff --git a/lib/tfw/components/pipe_io_server/__init__.py b/lib/tfw/components/pipe_io/pipe_io_server/__init__.py similarity index 100% rename from lib/tfw/components/pipe_io_server/__init__.py rename to lib/tfw/components/pipe_io/pipe_io_server/__init__.py diff --git a/lib/tfw/components/pipe_io_server/deque.py b/lib/tfw/components/pipe_io/pipe_io_server/deque.py similarity index 100% rename from lib/tfw/components/pipe_io_server/deque.py rename to lib/tfw/components/pipe_io/pipe_io_server/deque.py diff --git a/lib/tfw/components/pipe_io_server/pipe.py b/lib/tfw/components/pipe_io/pipe_io_server/pipe.py similarity index 100% rename from lib/tfw/components/pipe_io_server/pipe.py rename to lib/tfw/components/pipe_io/pipe_io_server/pipe.py diff --git a/lib/tfw/components/pipe_io_server/pipe_io_server.py b/lib/tfw/components/pipe_io/pipe_io_server/pipe_io_server.py similarity index 100% rename from lib/tfw/components/pipe_io_server/pipe_io_server.py rename to lib/tfw/components/pipe_io/pipe_io_server/pipe_io_server.py diff --git a/lib/tfw/components/pipe_io_server/pipe_reader_thread.py b/lib/tfw/components/pipe_io/pipe_io_server/pipe_reader_thread.py similarity index 100% rename from lib/tfw/components/pipe_io_server/pipe_reader_thread.py rename to lib/tfw/components/pipe_io/pipe_io_server/pipe_reader_thread.py diff --git a/lib/tfw/components/pipe_io_server/pipe_writer_thread.py b/lib/tfw/components/pipe_io/pipe_io_server/pipe_writer_thread.py similarity index 100% rename from lib/tfw/components/pipe_io_server/pipe_writer_thread.py rename to lib/tfw/components/pipe_io/pipe_io_server/pipe_writer_thread.py diff --git a/lib/tfw/components/pipe_io_server/terminate_process_on_failure.py b/lib/tfw/components/pipe_io/pipe_io_server/terminate_process_on_failure.py similarity index 100% rename from lib/tfw/components/pipe_io_server/terminate_process_on_failure.py rename to lib/tfw/components/pipe_io/pipe_io_server/terminate_process_on_failure.py diff --git a/lib/tfw/components/process_management/__init__.py b/lib/tfw/components/process_management/__init__.py new file mode 100644 index 0000000..8549b02 --- /dev/null +++ b/lib/tfw/components/process_management/__init__.py @@ -0,0 +1,2 @@ +from .process_handler import ProcessHandler +from .process_log_handler import ProcessLogHandler diff --git a/lib/tfw/components/log_inotify_observer.py b/lib/tfw/components/process_management/log_inotify_observer.py similarity index 84% rename from lib/tfw/components/log_inotify_observer.py rename to lib/tfw/components/process_management/log_inotify_observer.py index 4a21f08..94400ca 100644 --- a/lib/tfw/components/log_inotify_observer.py +++ b/lib/tfw/components/process_management/log_inotify_observer.py @@ -1,19 +1,19 @@ import logging -from tfw.networking import Scope +from tfw.internals.networking import Scope +from tfw.internals.inotify import InotifyObserver -from .inotify import InotifyObserver -from .supervisor import LogManager +from .supervisor import ProcessLogManager -class LogInotifyObserver(InotifyObserver, LogManager): +class LogInotifyObserver(InotifyObserver, ProcessLogManager): def __init__(self, server_connector, supervisor_uri, process_name, log_tail=0): self._prevent_log_recursion() self._server_connector = server_connector self._process_name = process_name self.log_tail = log_tail self._procinfo = None - LogManager.__init__(self, supervisor_uri) + ProcessLogManager.__init__(self, supervisor_uri) InotifyObserver.__init__(self, self._get_logfiles()) @staticmethod diff --git a/lib/tfw/builtins/process_managing_event_handler.py b/lib/tfw/components/process_management/process_handler.py similarity index 88% rename from lib/tfw/builtins/process_managing_event_handler.py rename to lib/tfw/components/process_management/process_handler.py index 41eb114..54928fd 100644 --- a/lib/tfw/builtins/process_managing_event_handler.py +++ b/lib/tfw/components/process_management/process_handler.py @@ -1,14 +1,15 @@ import logging from xmlrpc.client import Fault as SupervisorFault -from tfw.networking import Scope -from tfw.components import ProcessManager, LogManager +from tfw.internals.networking import Scope + +from .supervisor import ProcessManager, ProcessLogManager LOG = logging.getLogger(__name__) -class ProcessManagingEventHandler(ProcessManager, LogManager): +class ProcessHandler(ProcessManager, ProcessLogManager): keys = ['processmanager'] """ Event handler that can manage processes managed by supervisor. @@ -24,7 +25,7 @@ class ProcessManagingEventHandler(ProcessManager, LogManager): """ def __init__(self, *, supervisor_uri, log_tail=0): ProcessManager.__init__(self, supervisor_uri) - LogManager.__init__(self, supervisor_uri) + ProcessLogManager.__init__(self, supervisor_uri) self.log_tail = log_tail self.commands = { 'start': self.start_process, diff --git a/lib/tfw/builtins/log_monitoring_event_handler.py b/lib/tfw/components/process_management/process_log_handler.py similarity index 96% rename from lib/tfw/builtins/log_monitoring_event_handler.py rename to lib/tfw/components/process_management/process_log_handler.py index 54927eb..4ee084a 100644 --- a/lib/tfw/builtins/log_monitoring_event_handler.py +++ b/lib/tfw/components/process_management/process_log_handler.py @@ -1,12 +1,12 @@ import logging -from tfw.components import LogInotifyObserver +from .log_inotify_observer import LogInotifyObserver LOG = logging.getLogger(__name__) -class LogMonitoringEventHandler: +class ProcessLogHandler: keys = ['logmonitor'] """ Monitors the output of a supervisor process (stdout, stderr) and diff --git a/lib/tfw/components/supervisor.py b/lib/tfw/components/process_management/supervisor.py similarity index 96% rename from lib/tfw/components/supervisor.py rename to lib/tfw/components/process_management/supervisor.py index 83e8bc4..1e50d05 100644 --- a/lib/tfw/components/supervisor.py +++ b/lib/tfw/components/process_management/supervisor.py @@ -22,7 +22,7 @@ class ProcessManager(SupervisorBase): self.start_process(process_name) -class LogManager(SupervisorBase): +class ProcessLogManager(SupervisorBase): def read_stdout(self, process_name, tail=0): return self.supervisor.readProcessStdoutLog(process_name, -tail, 0) diff --git a/lib/tfw/components/snapshots/__init__.py b/lib/tfw/components/snapshots/__init__.py new file mode 100644 index 0000000..b9b3243 --- /dev/null +++ b/lib/tfw/components/snapshots/__init__.py @@ -0,0 +1 @@ +from .snapshot_handler import SnapshotHandler diff --git a/lib/tfw/builtins/directory_snapshotting_event_handler.py b/lib/tfw/components/snapshots/snapshot_handler.py similarity index 95% rename from lib/tfw/builtins/directory_snapshotting_event_handler.py rename to lib/tfw/components/snapshots/snapshot_handler.py index 91aff92..2ca9d28 100644 --- a/lib/tfw/builtins/directory_snapshotting_event_handler.py +++ b/lib/tfw/components/snapshots/snapshot_handler.py @@ -6,14 +6,15 @@ from datetime import datetime from dateutil import parser as dateparser -from tfw.components.snapshot_provider import SnapshotProvider -from tfw.networking import Scope +from tfw.internals.networking import Scope + +from .snapshot_provider import SnapshotProvider LOG = logging.getLogger(__name__) -class DirectorySnapshottingEventHandler: +class SnapshotHandler: keys = ['snapshot'] def __init__(self, *, directories, snapshots_dir, exclude_unix_patterns=None): diff --git a/lib/tfw/components/snapshot_provider.py b/lib/tfw/components/snapshots/snapshot_provider.py similarity index 100% rename from lib/tfw/components/snapshot_provider.py rename to lib/tfw/components/snapshots/snapshot_provider.py diff --git a/lib/tfw/components/terminal/__init__.py b/lib/tfw/components/terminal/__init__.py new file mode 100644 index 0000000..584df0d --- /dev/null +++ b/lib/tfw/components/terminal/__init__.py @@ -0,0 +1,3 @@ +from .terminal_handler import TerminalHandler +from .terminal_commands_handler import TerminalCommandsHandler +from .commands_equal import CommandsEqual diff --git a/lib/tfw/components/commands_equal.py b/lib/tfw/components/terminal/commands_equal.py similarity index 98% rename from lib/tfw/components/commands_equal.py rename to lib/tfw/components/terminal/commands_equal.py index b52aa6b..2e00d16 100644 --- a/lib/tfw/components/commands_equal.py +++ b/lib/tfw/components/terminal/commands_equal.py @@ -1,7 +1,7 @@ from shlex import split from re import search -from tfw.decorators.lazy_property import lazy_property +from tfw.internals.lazy import lazy_property class CommandsEqual: diff --git a/lib/tfw/components/history_monitor.py b/lib/tfw/components/terminal/history_monitor.py similarity index 98% rename from lib/tfw/components/history_monitor.py rename to lib/tfw/components/terminal/history_monitor.py index 899217d..26b230d 100644 --- a/lib/tfw/components/history_monitor.py +++ b/lib/tfw/components/terminal/history_monitor.py @@ -2,7 +2,7 @@ from re import findall from re import compile as compileregex from abc import ABC, abstractmethod -from tfw.components.inotify import InotifyObserver +from tfw.internals.inotify import InotifyObserver class HistoryMonitor(ABC, InotifyObserver): diff --git a/lib/tfw/components/terminado_mini_server.py b/lib/tfw/components/terminal/terminado_mini_server.py similarity index 100% rename from lib/tfw/components/terminado_mini_server.py rename to lib/tfw/components/terminal/terminado_mini_server.py diff --git a/lib/tfw/components/terminal_commands.py b/lib/tfw/components/terminal/terminal_commands.py similarity index 100% rename from lib/tfw/components/terminal_commands.py rename to lib/tfw/components/terminal/terminal_commands.py diff --git a/lib/tfw/builtins/terminal_commands_event_handler.py b/lib/tfw/components/terminal/terminal_commands_handler.py similarity index 58% rename from lib/tfw/builtins/terminal_commands_event_handler.py rename to lib/tfw/components/terminal/terminal_commands_handler.py index 2bb7399..dcfd5f0 100644 --- a/lib/tfw/builtins/terminal_commands_event_handler.py +++ b/lib/tfw/components/terminal/terminal_commands_handler.py @@ -1,7 +1,7 @@ -from tfw.components import TerminalCommands +from .terminal_commands import TerminalCommands -class TerminalCommandsEventHandler(TerminalCommands): +class TerminalCommandsHandler(TerminalCommands): keys = ['history.bash'] def handle_event(self, message, _): diff --git a/lib/tfw/builtins/terminal_event_handler.py b/lib/tfw/components/terminal/terminal_handler.py similarity index 95% rename from lib/tfw/builtins/terminal_event_handler.py rename to lib/tfw/components/terminal/terminal_handler.py index 6cee755..2cbdff4 100644 --- a/lib/tfw/builtins/terminal_event_handler.py +++ b/lib/tfw/components/terminal/terminal_handler.py @@ -1,12 +1,13 @@ import logging -from tfw.components import BashMonitor, TerminadoMiniServer +from .history_monitor import BashMonitor +from .terminado_mini_server import TerminadoMiniServer LOG = logging.getLogger(__name__) -class TerminalEventHandler: +class TerminalHandler: keys = ['shell'] """ Event handler responsible for managing terminal sessions for frontend xterm diff --git a/lib/tfw/event_handlers.py b/lib/tfw/event_handlers.py new file mode 100644 index 0000000..8dc872e --- /dev/null +++ b/lib/tfw/event_handlers.py @@ -0,0 +1,2 @@ +# pylint: disable=unused-import +from tfw.internals.event_handling import EventHandler, FSMAwareEventHandler diff --git a/lib/tfw/fsm/fsm_base.py b/lib/tfw/fsm/fsm_base.py index e4f9645..0fac40b 100644 --- a/lib/tfw/fsm/fsm_base.py +++ b/lib/tfw/fsm/fsm_base.py @@ -4,7 +4,7 @@ from datetime import datetime from transitions import Machine, MachineError -from tfw.mixins.callback_mixin import CallbackMixin +from tfw.internals.callback_mixin import CallbackMixin LOG = logging.getLogger(__name__) diff --git a/lib/tfw/fsm/linear_fsm.py b/lib/tfw/fsm/linear_fsm.py index 383f98e..354ffd2 100644 --- a/lib/tfw/fsm/linear_fsm.py +++ b/lib/tfw/fsm/linear_fsm.py @@ -1,6 +1,6 @@ from transitions import State -from tfw.fsm.fsm_base import FSMBase +from .fsm_base import FSMBase class LinearFSM(FSMBase): diff --git a/lib/tfw/fsm/yaml_fsm.py b/lib/tfw/fsm/yaml_fsm.py index facce7c..32c002b 100644 --- a/lib/tfw/fsm/yaml_fsm.py +++ b/lib/tfw/fsm/yaml_fsm.py @@ -6,7 +6,7 @@ import yaml import jinja2 from transitions import State -from tfw.fsm.fsm_base import FSMBase +from .fsm_base import FSMBase class YamlFSM(FSMBase): diff --git a/lib/tfw/decorators/__init__.py b/lib/tfw/internals/__init__.py similarity index 100% rename from lib/tfw/decorators/__init__.py rename to lib/tfw/internals/__init__.py diff --git a/lib/tfw/mixins/callback_mixin.py b/lib/tfw/internals/callback_mixin.py similarity index 95% rename from lib/tfw/mixins/callback_mixin.py rename to lib/tfw/internals/callback_mixin.py index 36b0f64..c54db5b 100644 --- a/lib/tfw/mixins/callback_mixin.py +++ b/lib/tfw/internals/callback_mixin.py @@ -1,6 +1,6 @@ from functools import partial -from tfw.decorators.lazy_property import lazy_property +from .lazy import lazy_property class CallbackMixin: diff --git a/lib/tfw/crypto.py b/lib/tfw/internals/crypto.py similarity index 96% rename from lib/tfw/crypto.py rename to lib/tfw/internals/crypto.py index 562420b..04aff16 100644 --- a/lib/tfw/crypto.py +++ b/lib/tfw/internals/crypto.py @@ -11,8 +11,8 @@ from cryptography.hazmat.primitives.hashes import SHA256 from cryptography.hazmat.primitives.hmac import HMAC as _HMAC from cryptography.exceptions import InvalidSignature -from tfw.networking import message_bytes -from tfw.decorators.lazy_property import lazy_property +from tfw.internals.networking import message_bytes +from tfw.internals.lazy import lazy_property from tfw.config import TFWENV diff --git a/lib/tfw/event_handlers/__init__.py b/lib/tfw/internals/event_handling/__init__.py similarity index 100% rename from lib/tfw/event_handlers/__init__.py rename to lib/tfw/internals/event_handling/__init__.py diff --git a/lib/tfw/event_handlers/event_handler.py b/lib/tfw/internals/event_handling/event_handler.py similarity index 100% rename from lib/tfw/event_handlers/event_handler.py rename to lib/tfw/internals/event_handling/event_handler.py diff --git a/lib/tfw/event_handlers/event_handler_factory_base.py b/lib/tfw/internals/event_handling/event_handler_factory_base.py similarity index 100% rename from lib/tfw/event_handlers/event_handler_factory_base.py rename to lib/tfw/internals/event_handling/event_handler_factory_base.py diff --git a/lib/tfw/event_handlers/fsm_aware.py b/lib/tfw/internals/event_handling/fsm_aware.py similarity index 94% rename from lib/tfw/event_handlers/fsm_aware.py rename to lib/tfw/internals/event_handling/fsm_aware.py index 76d8d3f..5254e68 100644 --- a/lib/tfw/event_handlers/fsm_aware.py +++ b/lib/tfw/internals/event_handling/fsm_aware.py @@ -1,6 +1,6 @@ import logging -from tfw.crypto import KeyManager, verify_message +from tfw.internals.crypto import KeyManager, verify_message LOG = logging.getLogger(__name__) diff --git a/lib/tfw/event_handlers/fsm_aware_event_handler.py b/lib/tfw/internals/event_handling/fsm_aware_event_handler.py similarity index 100% rename from lib/tfw/event_handlers/fsm_aware_event_handler.py rename to lib/tfw/internals/event_handling/fsm_aware_event_handler.py diff --git a/lib/tfw/event_handlers/test_event_handler.py b/lib/tfw/internals/event_handling/test_event_handler.py similarity index 100% rename from lib/tfw/event_handlers/test_event_handler.py rename to lib/tfw/internals/event_handling/test_event_handler.py diff --git a/lib/tfw/components/inotify/__init__.py b/lib/tfw/internals/inotify/__init__.py similarity index 100% rename from lib/tfw/components/inotify/__init__.py rename to lib/tfw/internals/inotify/__init__.py diff --git a/lib/tfw/components/inotify/inotify.py b/lib/tfw/internals/inotify/inotify.py similarity index 100% rename from lib/tfw/components/inotify/inotify.py rename to lib/tfw/internals/inotify/inotify.py diff --git a/lib/tfw/components/inotify/test_inotify.py b/lib/tfw/internals/inotify/test_inotify.py similarity index 100% rename from lib/tfw/components/inotify/test_inotify.py rename to lib/tfw/internals/inotify/test_inotify.py diff --git a/lib/tfw/decorators/lazy_property.py b/lib/tfw/internals/lazy.py similarity index 100% rename from lib/tfw/decorators/lazy_property.py rename to lib/tfw/internals/lazy.py diff --git a/lib/tfw/networking/__init__.py b/lib/tfw/internals/networking/__init__.py similarity index 100% rename from lib/tfw/networking/__init__.py rename to lib/tfw/internals/networking/__init__.py diff --git a/lib/tfw/networking/event_handler_connector.py b/lib/tfw/internals/networking/event_handler_connector.py similarity index 100% rename from lib/tfw/networking/event_handler_connector.py rename to lib/tfw/internals/networking/event_handler_connector.py diff --git a/lib/tfw/networking/scope.py b/lib/tfw/internals/networking/scope.py similarity index 100% rename from lib/tfw/networking/scope.py rename to lib/tfw/internals/networking/scope.py diff --git a/lib/tfw/networking/serialization.py b/lib/tfw/internals/networking/serialization.py similarity index 100% rename from lib/tfw/networking/serialization.py rename to lib/tfw/internals/networking/serialization.py diff --git a/lib/tfw/networking/server_connector.py b/lib/tfw/internals/networking/server_connector.py similarity index 100% rename from lib/tfw/networking/server_connector.py rename to lib/tfw/internals/networking/server_connector.py diff --git a/lib/tfw/internals/server/__init__.py b/lib/tfw/internals/server/__init__.py new file mode 100644 index 0000000..73e3f40 --- /dev/null +++ b/lib/tfw/internals/server/__init__.py @@ -0,0 +1 @@ +from .zmq_websocket_router import ZMQWebSocketRouter diff --git a/lib/tfw/server/zmq_websocket_router.py b/lib/tfw/internals/server/zmq_websocket_router.py similarity index 97% rename from lib/tfw/server/zmq_websocket_router.py rename to lib/tfw/internals/server/zmq_websocket_router.py index b7adf16..cdafc2f 100644 --- a/lib/tfw/server/zmq_websocket_router.py +++ b/lib/tfw/internals/server/zmq_websocket_router.py @@ -3,7 +3,7 @@ import logging from tornado.websocket import WebSocketHandler -from tfw.networking import Scope +from tfw.internals.networking import Scope LOG = logging.getLogger(__name__) diff --git a/lib/tfw/logging.py b/lib/tfw/logging.py index d405adb..dad7499 100644 --- a/lib/tfw/logging.py +++ b/lib/tfw/logging.py @@ -102,7 +102,7 @@ class LogFormatter(Formatter): class VerboseLogFormatter(Formatter): - def format(self, record): + def format(self, record): # pylint: disable=no-self-use date = datetime.utcfromtimestamp(record.created).strftime('%H:%M:%S') if record.args: message = record.msg % record.args diff --git a/lib/tfw/main/__init__.py b/lib/tfw/main/__init__.py index 9e1c892..3e731f9 100644 --- a/lib/tfw/main/__init__.py +++ b/lib/tfw/main/__init__.py @@ -1,3 +1,4 @@ from .tfw_connector import TFWUplinkConnector, TFWConnector from .event_handler_factory import EventHandlerFactory from .signal_handling import setup_signal_handlers +from .tfw_server import TFWServer diff --git a/lib/tfw/main/event_handler_factory.py b/lib/tfw/main/event_handler_factory.py index 271be8c..c2c4045 100644 --- a/lib/tfw/main/event_handler_factory.py +++ b/lib/tfw/main/event_handler_factory.py @@ -1,4 +1,4 @@ -from tfw.event_handlers import EventHandlerFactoryBase +from tfw.internals.event_handling import EventHandlerFactoryBase from .tfw_connector import TFWConnector diff --git a/lib/tfw/main/signal_handling.py b/lib/tfw/main/signal_handling.py index a8750ef..387c77d 100644 --- a/lib/tfw/main/signal_handling.py +++ b/lib/tfw/main/signal_handling.py @@ -1,6 +1,6 @@ from signal import signal, SIGTERM, SIGINT -from tfw.event_handlers import EventHandler +from tfw.internals.event_handling import EventHandler def setup_signal_handlers(): diff --git a/lib/tfw/main/tfw_connector.py b/lib/tfw/main/tfw_connector.py index 2e56996..5324ee6 100644 --- a/lib/tfw/main/tfw_connector.py +++ b/lib/tfw/main/tfw_connector.py @@ -1,4 +1,4 @@ -from tfw.networking import ServerConnector, ServerUplinkConnector +from tfw.internals.networking import ServerConnector, ServerUplinkConnector from tfw.config import TFWENV diff --git a/lib/tfw/server/tfw_server.py b/lib/tfw/main/tfw_server.py similarity index 88% rename from lib/tfw/server/tfw_server.py rename to lib/tfw/main/tfw_server.py index d524265..22d216f 100644 --- a/lib/tfw/server/tfw_server.py +++ b/lib/tfw/main/tfw_server.py @@ -2,10 +2,10 @@ import logging from tornado.web import Application -from tfw.networking import EventHandlerConnector +from tfw.internals.networking import EventHandlerConnector +from tfw.internals.server import ZMQWebSocketRouter from tfw.config import TFWENV -from .zmq_websocket_router import ZMQWebSocketRouter LOG = logging.getLogger(__name__) diff --git a/lib/tfw/mixins/__init__.py b/lib/tfw/mixins/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/lib/tfw/server/__init__.py b/lib/tfw/server/__init__.py deleted file mode 100644 index e2c01a9..0000000 --- a/lib/tfw/server/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .tfw_server import TFWServer diff --git a/supervisor/tfw_server.py b/supervisor/tfw_server.py index 812873c..f3ad4be 100644 --- a/supervisor/tfw_server.py +++ b/supervisor/tfw_server.py @@ -2,7 +2,7 @@ from sys import stderr from tornado.ioloop import IOLoop -from tfw.server import TFWServer +from tfw.main import TFWServer from tfw.config import TFWENV from tfw.logging import Log, Logger, LogFormatter, VerboseLogFormatter From 52399f413ca4e8754dc14645d8f1f3af14e24d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Wed, 24 Jul 2019 15:50:41 +0200 Subject: [PATCH 15/18] Simplify package structure --- Dockerfile | 6 ++--- lib/tao/config/__init__.py | 1 - lib/tao/config/envvars.py | 3 --- lib/tfw/config/__init__.py | 1 - lib/tfw/config/envvars.py | 3 --- lib/tfw/internals/__init__.py | 0 setup.py | 26 +++++++++---------- {lib/tao => tfw}/__init__.py | 0 {lib/tfw => tfw/components}/__init__.py | 0 .../components/frontend/__init__.py | 0 .../components/frontend/frontend_handler.py | 0 .../components/frontend/message_sender.py | 0 .../components/frontend/message_storage.py | 0 {lib/tfw => tfw}/components/fsm/__init__.py | 0 .../tfw => tfw}/components/fsm/fsm_handler.py | 0 .../tfw => tfw}/components/fsm/fsm_updater.py | 0 {lib/tfw => tfw}/components/ide/__init__.py | 0 .../components/ide/file_manager/__init__.py | 0 .../ide/file_manager/file_manager.py | 0 .../ide/file_manager/test_file_manager.py | 0 .../tfw => tfw}/components/ide/ide_handler.py | 0 .../components/pipe_io/__init__.py | 0 .../components/pipe_io/pipe_io_handler.py | 0 .../pipe_io/pipe_io_server/__init__.py | 0 .../pipe_io/pipe_io_server/deque.py | 0 .../components/pipe_io/pipe_io_server/pipe.py | 0 .../pipe_io/pipe_io_server/pipe_io_server.py | 0 .../pipe_io_server/pipe_reader_thread.py | 0 .../pipe_io_server/pipe_writer_thread.py | 0 .../terminate_process_on_failure.py | 0 .../components/process_management/__init__.py | 0 .../log_inotify_observer.py | 0 .../process_management/process_handler.py | 0 .../process_management/process_log_handler.py | 0 .../process_management/supervisor.py | 0 .../components/snapshots/__init__.py | 0 .../components/snapshots/snapshot_handler.py | 0 .../components/snapshots/snapshot_provider.py | 0 .../components/terminal/__init__.py | 0 .../components/terminal/commands_equal.py | 0 .../components/terminal/history_monitor.py | 0 .../terminal/terminado_mini_server.py | 0 .../components/terminal/terminal_commands.py | 0 .../terminal/terminal_commands_handler.py | 0 .../components/terminal/terminal_handler.py | 0 tfw/config/__init__.py | 1 + tfw/config/envvars.py | 5 ++++ .../config/lazy_environment.py | 0 {lib/tfw => tfw}/event_handlers.py | 0 {lib/tfw => tfw}/fsm/__init__.py | 0 {lib/tfw => tfw}/fsm/fsm_base.py | 0 {lib/tfw => tfw}/fsm/linear_fsm.py | 0 {lib/tfw => tfw}/fsm/yaml_fsm.py | 0 .../components => tfw/internals}/__init__.py | 0 {lib/tfw => tfw}/internals/callback_mixin.py | 0 {lib/tfw => tfw}/internals/crypto.py | 0 .../internals/event_handling/__init__.py | 0 .../internals/event_handling/event_handler.py | 0 .../event_handler_factory_base.py | 0 .../internals/event_handling/fsm_aware.py | 0 .../event_handling/fsm_aware_event_handler.py | 0 .../event_handling/test_event_handler.py | 0 .../tfw => tfw}/internals/inotify/__init__.py | 0 {lib/tfw => tfw}/internals/inotify/inotify.py | 0 .../internals/inotify/test_inotify.py | 0 {lib/tfw => tfw}/internals/lazy.py | 0 .../internals/networking/__init__.py | 0 .../networking/event_handler_connector.py | 0 .../tfw => tfw}/internals/networking/scope.py | 0 .../internals/networking/serialization.py | 0 .../internals/networking/server_connector.py | 0 {lib/tfw => tfw}/internals/server/__init__.py | 0 .../internals/server/zmq_websocket_router.py | 0 {lib/tfw => tfw}/logging.py | 0 {lib/tfw => tfw}/main/__init__.py | 0 .../tfw => tfw}/main/event_handler_factory.py | 0 {lib/tfw => tfw}/main/signal_handling.py | 0 {lib/tfw => tfw}/main/tfw_connector.py | 0 {lib/tfw => tfw}/main/tfw_server.py | 0 79 files changed, 22 insertions(+), 24 deletions(-) delete mode 100644 lib/tao/config/__init__.py delete mode 100644 lib/tao/config/envvars.py delete mode 100644 lib/tfw/config/__init__.py delete mode 100644 lib/tfw/config/envvars.py delete mode 100644 lib/tfw/internals/__init__.py rename {lib/tao => tfw}/__init__.py (100%) rename {lib/tfw => tfw/components}/__init__.py (100%) rename {lib/tfw => tfw}/components/frontend/__init__.py (100%) rename {lib/tfw => tfw}/components/frontend/frontend_handler.py (100%) rename {lib/tfw => tfw}/components/frontend/message_sender.py (100%) rename {lib/tfw => tfw}/components/frontend/message_storage.py (100%) rename {lib/tfw => tfw}/components/fsm/__init__.py (100%) rename {lib/tfw => tfw}/components/fsm/fsm_handler.py (100%) rename {lib/tfw => tfw}/components/fsm/fsm_updater.py (100%) rename {lib/tfw => tfw}/components/ide/__init__.py (100%) rename {lib/tfw => tfw}/components/ide/file_manager/__init__.py (100%) rename {lib/tfw => tfw}/components/ide/file_manager/file_manager.py (100%) rename {lib/tfw => tfw}/components/ide/file_manager/test_file_manager.py (100%) rename {lib/tfw => tfw}/components/ide/ide_handler.py (100%) rename {lib/tfw => tfw}/components/pipe_io/__init__.py (100%) rename {lib/tfw => tfw}/components/pipe_io/pipe_io_handler.py (100%) rename {lib/tfw => tfw}/components/pipe_io/pipe_io_server/__init__.py (100%) rename {lib/tfw => tfw}/components/pipe_io/pipe_io_server/deque.py (100%) rename {lib/tfw => tfw}/components/pipe_io/pipe_io_server/pipe.py (100%) rename {lib/tfw => tfw}/components/pipe_io/pipe_io_server/pipe_io_server.py (100%) rename {lib/tfw => tfw}/components/pipe_io/pipe_io_server/pipe_reader_thread.py (100%) rename {lib/tfw => tfw}/components/pipe_io/pipe_io_server/pipe_writer_thread.py (100%) rename {lib/tfw => tfw}/components/pipe_io/pipe_io_server/terminate_process_on_failure.py (100%) rename {lib/tfw => tfw}/components/process_management/__init__.py (100%) rename {lib/tfw => tfw}/components/process_management/log_inotify_observer.py (100%) rename {lib/tfw => tfw}/components/process_management/process_handler.py (100%) rename {lib/tfw => tfw}/components/process_management/process_log_handler.py (100%) rename {lib/tfw => tfw}/components/process_management/supervisor.py (100%) rename {lib/tfw => tfw}/components/snapshots/__init__.py (100%) rename {lib/tfw => tfw}/components/snapshots/snapshot_handler.py (100%) rename {lib/tfw => tfw}/components/snapshots/snapshot_provider.py (100%) rename {lib/tfw => tfw}/components/terminal/__init__.py (100%) rename {lib/tfw => tfw}/components/terminal/commands_equal.py (100%) rename {lib/tfw => tfw}/components/terminal/history_monitor.py (100%) rename {lib/tfw => tfw}/components/terminal/terminado_mini_server.py (100%) rename {lib/tfw => tfw}/components/terminal/terminal_commands.py (100%) rename {lib/tfw => tfw}/components/terminal/terminal_commands_handler.py (100%) rename {lib/tfw => tfw}/components/terminal/terminal_handler.py (100%) create mode 100644 tfw/config/__init__.py create mode 100644 tfw/config/envvars.py rename lib/envvars/__init__.py => tfw/config/lazy_environment.py (100%) rename {lib/tfw => tfw}/event_handlers.py (100%) rename {lib/tfw => tfw}/fsm/__init__.py (100%) rename {lib/tfw => tfw}/fsm/fsm_base.py (100%) rename {lib/tfw => tfw}/fsm/linear_fsm.py (100%) rename {lib/tfw => tfw}/fsm/yaml_fsm.py (100%) rename {lib/tfw/components => tfw/internals}/__init__.py (100%) rename {lib/tfw => tfw}/internals/callback_mixin.py (100%) rename {lib/tfw => tfw}/internals/crypto.py (100%) rename {lib/tfw => tfw}/internals/event_handling/__init__.py (100%) rename {lib/tfw => tfw}/internals/event_handling/event_handler.py (100%) rename {lib/tfw => tfw}/internals/event_handling/event_handler_factory_base.py (100%) rename {lib/tfw => tfw}/internals/event_handling/fsm_aware.py (100%) rename {lib/tfw => tfw}/internals/event_handling/fsm_aware_event_handler.py (100%) rename {lib/tfw => tfw}/internals/event_handling/test_event_handler.py (100%) rename {lib/tfw => tfw}/internals/inotify/__init__.py (100%) rename {lib/tfw => tfw}/internals/inotify/inotify.py (100%) rename {lib/tfw => tfw}/internals/inotify/test_inotify.py (100%) rename {lib/tfw => tfw}/internals/lazy.py (100%) rename {lib/tfw => tfw}/internals/networking/__init__.py (100%) rename {lib/tfw => tfw}/internals/networking/event_handler_connector.py (100%) rename {lib/tfw => tfw}/internals/networking/scope.py (100%) rename {lib/tfw => tfw}/internals/networking/serialization.py (100%) rename {lib/tfw => tfw}/internals/networking/server_connector.py (100%) rename {lib/tfw => tfw}/internals/server/__init__.py (100%) rename {lib/tfw => tfw}/internals/server/zmq_websocket_router.py (100%) rename {lib/tfw => tfw}/logging.py (100%) rename {lib/tfw => tfw}/main/__init__.py (100%) rename {lib/tfw => tfw}/main/event_handler_factory.py (100%) rename {lib/tfw => tfw}/main/signal_handling.py (100%) rename {lib/tfw => tfw}/main/tfw_connector.py (100%) rename {lib/tfw => tfw}/main/tfw_server.py (100%) diff --git a/Dockerfile b/Dockerfile index 1290e10..5df5cf4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -54,10 +54,10 @@ COPY supervisor/components/ ${TFW_SUPERVISORD_COMPONENTS} COPY nginx/nginx.conf ${TFW_NGINX_CONF} COPY nginx/default.conf ${TFW_NGINX_DEFAULT} COPY nginx/components/ ${TFW_NGINX_COMPONENTS} -COPY lib ${TFW_LIB_DIR}/ +COPY tfw ${TFW_LIB_DIR}/tfw COPY supervisor/tfw_server.py ${TFW_SERVER_DIR}/ -RUN for dir in "${TFW_LIB_DIR}"/{tfw,tao,envvars} "/etc/nginx" "/etc/supervisor"; do \ +RUN for dir in "${TFW_LIB_DIR}"/tfw "/etc/nginx" "/etc/supervisor"; do \ chown -R root:root "$dir" && chmod -R 700 "$dir"; \ done @@ -70,7 +70,7 @@ ONBUILD COPY ${BUILD_CONTEXT}/supervisor/ ${TFW_SUPERVISORD_COMPONENTS} ONBUILD RUN for f in "${TFW_NGINX_DEFAULT}" ${TFW_NGINX_COMPONENTS}/*.conf; do \ envsubst "$(printenv | cut -d= -f1 | grep TFW_ | sed -e 's/^/$/g')" < $f > $f~ && mv $f~ $f ;\ done -ONBUILD VOLUME ["/etc/nginx", "/var/lib/nginx", "/var/log/nginx", "${TFW_LIB_DIR}/envvars", "${TFW_LIB_DIR}/tfw"] +ONBUILD VOLUME ["/etc/nginx", "/var/lib/nginx", "/var/log/nginx", "${TFW_LIB_DIR}/tfw"] ONBUILD COPY ${BUILD_CONTEXT}/frontend /data/ ONBUILD RUN test -z "${NOFRONTEND}" && cd /data && yarn install --frozen-lockfile || : diff --git a/lib/tao/config/__init__.py b/lib/tao/config/__init__.py deleted file mode 100644 index fd07e8b..0000000 --- a/lib/tao/config/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .envvars import TAOENV diff --git a/lib/tao/config/envvars.py b/lib/tao/config/envvars.py deleted file mode 100644 index 813d06f..0000000 --- a/lib/tao/config/envvars.py +++ /dev/null @@ -1,3 +0,0 @@ -from envvars import LazyEnvironment - -TAOENV = LazyEnvironment('AVATAO_', 'taoenvtuple').environment diff --git a/lib/tfw/config/__init__.py b/lib/tfw/config/__init__.py deleted file mode 100644 index b9719ef..0000000 --- a/lib/tfw/config/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .envvars import TFWENV diff --git a/lib/tfw/config/envvars.py b/lib/tfw/config/envvars.py deleted file mode 100644 index 68adb0e..0000000 --- a/lib/tfw/config/envvars.py +++ /dev/null @@ -1,3 +0,0 @@ -from envvars import LazyEnvironment - -TFWENV = LazyEnvironment('TFW_', 'tfwenvtuple').environment diff --git a/lib/tfw/internals/__init__.py b/lib/tfw/internals/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/setup.py b/setup.py index e5fa212..c4c7912 100644 --- a/setup.py +++ b/setup.py @@ -1,6 +1,6 @@ from os.path import dirname, realpath, join -from setuptools import setup, find_packages +from setuptools import setup here = dirname(realpath(__file__)) @@ -10,20 +10,20 @@ with open(join(here, 'requirements.txt'), 'r') as ifile: requirements = ifile.read().splitlines() setup( - name = 'tfw', - version = version, - description = 'Avatao tutorial-framework', - url = 'https://github.com/avatao-content/baseimage-tutorial-framework', - author = 'Avatao.com Innovative Learning Kft.', - author_email = 'support@avatao.com', - license = 'custom', - packages = find_packages('lib'), - package_dir = {'': 'lib'}, - install_requires = requirements, - extras_require = { + name='tfw', + version=version, + description='Avatao tutorial-framework', + url='https://github.com/avatao-content/baseimage-tutorial-framework', + author='Avatao.com Innovative Learning Kft.', + author_email='support@avatao.com', + license='custom', + packages=['tfw'], + package_dir={'tfw': 'tfw'}, + install_requires=requirements, + extras_require={ 'docs': [ 'sphinx >= 1.7.0', ], }, - zip_safe = False, + zip_safe=False, ) diff --git a/lib/tao/__init__.py b/tfw/__init__.py similarity index 100% rename from lib/tao/__init__.py rename to tfw/__init__.py diff --git a/lib/tfw/__init__.py b/tfw/components/__init__.py similarity index 100% rename from lib/tfw/__init__.py rename to tfw/components/__init__.py diff --git a/lib/tfw/components/frontend/__init__.py b/tfw/components/frontend/__init__.py similarity index 100% rename from lib/tfw/components/frontend/__init__.py rename to tfw/components/frontend/__init__.py diff --git a/lib/tfw/components/frontend/frontend_handler.py b/tfw/components/frontend/frontend_handler.py similarity index 100% rename from lib/tfw/components/frontend/frontend_handler.py rename to tfw/components/frontend/frontend_handler.py diff --git a/lib/tfw/components/frontend/message_sender.py b/tfw/components/frontend/message_sender.py similarity index 100% rename from lib/tfw/components/frontend/message_sender.py rename to tfw/components/frontend/message_sender.py diff --git a/lib/tfw/components/frontend/message_storage.py b/tfw/components/frontend/message_storage.py similarity index 100% rename from lib/tfw/components/frontend/message_storage.py rename to tfw/components/frontend/message_storage.py diff --git a/lib/tfw/components/fsm/__init__.py b/tfw/components/fsm/__init__.py similarity index 100% rename from lib/tfw/components/fsm/__init__.py rename to tfw/components/fsm/__init__.py diff --git a/lib/tfw/components/fsm/fsm_handler.py b/tfw/components/fsm/fsm_handler.py similarity index 100% rename from lib/tfw/components/fsm/fsm_handler.py rename to tfw/components/fsm/fsm_handler.py diff --git a/lib/tfw/components/fsm/fsm_updater.py b/tfw/components/fsm/fsm_updater.py similarity index 100% rename from lib/tfw/components/fsm/fsm_updater.py rename to tfw/components/fsm/fsm_updater.py diff --git a/lib/tfw/components/ide/__init__.py b/tfw/components/ide/__init__.py similarity index 100% rename from lib/tfw/components/ide/__init__.py rename to tfw/components/ide/__init__.py diff --git a/lib/tfw/components/ide/file_manager/__init__.py b/tfw/components/ide/file_manager/__init__.py similarity index 100% rename from lib/tfw/components/ide/file_manager/__init__.py rename to tfw/components/ide/file_manager/__init__.py diff --git a/lib/tfw/components/ide/file_manager/file_manager.py b/tfw/components/ide/file_manager/file_manager.py similarity index 100% rename from lib/tfw/components/ide/file_manager/file_manager.py rename to tfw/components/ide/file_manager/file_manager.py diff --git a/lib/tfw/components/ide/file_manager/test_file_manager.py b/tfw/components/ide/file_manager/test_file_manager.py similarity index 100% rename from lib/tfw/components/ide/file_manager/test_file_manager.py rename to tfw/components/ide/file_manager/test_file_manager.py diff --git a/lib/tfw/components/ide/ide_handler.py b/tfw/components/ide/ide_handler.py similarity index 100% rename from lib/tfw/components/ide/ide_handler.py rename to tfw/components/ide/ide_handler.py diff --git a/lib/tfw/components/pipe_io/__init__.py b/tfw/components/pipe_io/__init__.py similarity index 100% rename from lib/tfw/components/pipe_io/__init__.py rename to tfw/components/pipe_io/__init__.py diff --git a/lib/tfw/components/pipe_io/pipe_io_handler.py b/tfw/components/pipe_io/pipe_io_handler.py similarity index 100% rename from lib/tfw/components/pipe_io/pipe_io_handler.py rename to tfw/components/pipe_io/pipe_io_handler.py diff --git a/lib/tfw/components/pipe_io/pipe_io_server/__init__.py b/tfw/components/pipe_io/pipe_io_server/__init__.py similarity index 100% rename from lib/tfw/components/pipe_io/pipe_io_server/__init__.py rename to tfw/components/pipe_io/pipe_io_server/__init__.py diff --git a/lib/tfw/components/pipe_io/pipe_io_server/deque.py b/tfw/components/pipe_io/pipe_io_server/deque.py similarity index 100% rename from lib/tfw/components/pipe_io/pipe_io_server/deque.py rename to tfw/components/pipe_io/pipe_io_server/deque.py diff --git a/lib/tfw/components/pipe_io/pipe_io_server/pipe.py b/tfw/components/pipe_io/pipe_io_server/pipe.py similarity index 100% rename from lib/tfw/components/pipe_io/pipe_io_server/pipe.py rename to tfw/components/pipe_io/pipe_io_server/pipe.py diff --git a/lib/tfw/components/pipe_io/pipe_io_server/pipe_io_server.py b/tfw/components/pipe_io/pipe_io_server/pipe_io_server.py similarity index 100% rename from lib/tfw/components/pipe_io/pipe_io_server/pipe_io_server.py rename to tfw/components/pipe_io/pipe_io_server/pipe_io_server.py diff --git a/lib/tfw/components/pipe_io/pipe_io_server/pipe_reader_thread.py b/tfw/components/pipe_io/pipe_io_server/pipe_reader_thread.py similarity index 100% rename from lib/tfw/components/pipe_io/pipe_io_server/pipe_reader_thread.py rename to tfw/components/pipe_io/pipe_io_server/pipe_reader_thread.py diff --git a/lib/tfw/components/pipe_io/pipe_io_server/pipe_writer_thread.py b/tfw/components/pipe_io/pipe_io_server/pipe_writer_thread.py similarity index 100% rename from lib/tfw/components/pipe_io/pipe_io_server/pipe_writer_thread.py rename to tfw/components/pipe_io/pipe_io_server/pipe_writer_thread.py diff --git a/lib/tfw/components/pipe_io/pipe_io_server/terminate_process_on_failure.py b/tfw/components/pipe_io/pipe_io_server/terminate_process_on_failure.py similarity index 100% rename from lib/tfw/components/pipe_io/pipe_io_server/terminate_process_on_failure.py rename to tfw/components/pipe_io/pipe_io_server/terminate_process_on_failure.py diff --git a/lib/tfw/components/process_management/__init__.py b/tfw/components/process_management/__init__.py similarity index 100% rename from lib/tfw/components/process_management/__init__.py rename to tfw/components/process_management/__init__.py diff --git a/lib/tfw/components/process_management/log_inotify_observer.py b/tfw/components/process_management/log_inotify_observer.py similarity index 100% rename from lib/tfw/components/process_management/log_inotify_observer.py rename to tfw/components/process_management/log_inotify_observer.py diff --git a/lib/tfw/components/process_management/process_handler.py b/tfw/components/process_management/process_handler.py similarity index 100% rename from lib/tfw/components/process_management/process_handler.py rename to tfw/components/process_management/process_handler.py diff --git a/lib/tfw/components/process_management/process_log_handler.py b/tfw/components/process_management/process_log_handler.py similarity index 100% rename from lib/tfw/components/process_management/process_log_handler.py rename to tfw/components/process_management/process_log_handler.py diff --git a/lib/tfw/components/process_management/supervisor.py b/tfw/components/process_management/supervisor.py similarity index 100% rename from lib/tfw/components/process_management/supervisor.py rename to tfw/components/process_management/supervisor.py diff --git a/lib/tfw/components/snapshots/__init__.py b/tfw/components/snapshots/__init__.py similarity index 100% rename from lib/tfw/components/snapshots/__init__.py rename to tfw/components/snapshots/__init__.py diff --git a/lib/tfw/components/snapshots/snapshot_handler.py b/tfw/components/snapshots/snapshot_handler.py similarity index 100% rename from lib/tfw/components/snapshots/snapshot_handler.py rename to tfw/components/snapshots/snapshot_handler.py diff --git a/lib/tfw/components/snapshots/snapshot_provider.py b/tfw/components/snapshots/snapshot_provider.py similarity index 100% rename from lib/tfw/components/snapshots/snapshot_provider.py rename to tfw/components/snapshots/snapshot_provider.py diff --git a/lib/tfw/components/terminal/__init__.py b/tfw/components/terminal/__init__.py similarity index 100% rename from lib/tfw/components/terminal/__init__.py rename to tfw/components/terminal/__init__.py diff --git a/lib/tfw/components/terminal/commands_equal.py b/tfw/components/terminal/commands_equal.py similarity index 100% rename from lib/tfw/components/terminal/commands_equal.py rename to tfw/components/terminal/commands_equal.py diff --git a/lib/tfw/components/terminal/history_monitor.py b/tfw/components/terminal/history_monitor.py similarity index 100% rename from lib/tfw/components/terminal/history_monitor.py rename to tfw/components/terminal/history_monitor.py diff --git a/lib/tfw/components/terminal/terminado_mini_server.py b/tfw/components/terminal/terminado_mini_server.py similarity index 100% rename from lib/tfw/components/terminal/terminado_mini_server.py rename to tfw/components/terminal/terminado_mini_server.py diff --git a/lib/tfw/components/terminal/terminal_commands.py b/tfw/components/terminal/terminal_commands.py similarity index 100% rename from lib/tfw/components/terminal/terminal_commands.py rename to tfw/components/terminal/terminal_commands.py diff --git a/lib/tfw/components/terminal/terminal_commands_handler.py b/tfw/components/terminal/terminal_commands_handler.py similarity index 100% rename from lib/tfw/components/terminal/terminal_commands_handler.py rename to tfw/components/terminal/terminal_commands_handler.py diff --git a/lib/tfw/components/terminal/terminal_handler.py b/tfw/components/terminal/terminal_handler.py similarity index 100% rename from lib/tfw/components/terminal/terminal_handler.py rename to tfw/components/terminal/terminal_handler.py diff --git a/tfw/config/__init__.py b/tfw/config/__init__.py new file mode 100644 index 0000000..f5476e9 --- /dev/null +++ b/tfw/config/__init__.py @@ -0,0 +1 @@ +from .envvars import TFWENV, TAOENV diff --git a/tfw/config/envvars.py b/tfw/config/envvars.py new file mode 100644 index 0000000..1e4c89a --- /dev/null +++ b/tfw/config/envvars.py @@ -0,0 +1,5 @@ +from .lazy_environment import LazyEnvironment + + +TFWENV = LazyEnvironment('TFW_', 'tfwenvtuple').environment +TAOENV = LazyEnvironment('AVATAO_', 'taoenvtuple').environment diff --git a/lib/envvars/__init__.py b/tfw/config/lazy_environment.py similarity index 100% rename from lib/envvars/__init__.py rename to tfw/config/lazy_environment.py diff --git a/lib/tfw/event_handlers.py b/tfw/event_handlers.py similarity index 100% rename from lib/tfw/event_handlers.py rename to tfw/event_handlers.py diff --git a/lib/tfw/fsm/__init__.py b/tfw/fsm/__init__.py similarity index 100% rename from lib/tfw/fsm/__init__.py rename to tfw/fsm/__init__.py diff --git a/lib/tfw/fsm/fsm_base.py b/tfw/fsm/fsm_base.py similarity index 100% rename from lib/tfw/fsm/fsm_base.py rename to tfw/fsm/fsm_base.py diff --git a/lib/tfw/fsm/linear_fsm.py b/tfw/fsm/linear_fsm.py similarity index 100% rename from lib/tfw/fsm/linear_fsm.py rename to tfw/fsm/linear_fsm.py diff --git a/lib/tfw/fsm/yaml_fsm.py b/tfw/fsm/yaml_fsm.py similarity index 100% rename from lib/tfw/fsm/yaml_fsm.py rename to tfw/fsm/yaml_fsm.py diff --git a/lib/tfw/components/__init__.py b/tfw/internals/__init__.py similarity index 100% rename from lib/tfw/components/__init__.py rename to tfw/internals/__init__.py diff --git a/lib/tfw/internals/callback_mixin.py b/tfw/internals/callback_mixin.py similarity index 100% rename from lib/tfw/internals/callback_mixin.py rename to tfw/internals/callback_mixin.py diff --git a/lib/tfw/internals/crypto.py b/tfw/internals/crypto.py similarity index 100% rename from lib/tfw/internals/crypto.py rename to tfw/internals/crypto.py diff --git a/lib/tfw/internals/event_handling/__init__.py b/tfw/internals/event_handling/__init__.py similarity index 100% rename from lib/tfw/internals/event_handling/__init__.py rename to tfw/internals/event_handling/__init__.py diff --git a/lib/tfw/internals/event_handling/event_handler.py b/tfw/internals/event_handling/event_handler.py similarity index 100% rename from lib/tfw/internals/event_handling/event_handler.py rename to tfw/internals/event_handling/event_handler.py diff --git a/lib/tfw/internals/event_handling/event_handler_factory_base.py b/tfw/internals/event_handling/event_handler_factory_base.py similarity index 100% rename from lib/tfw/internals/event_handling/event_handler_factory_base.py rename to tfw/internals/event_handling/event_handler_factory_base.py diff --git a/lib/tfw/internals/event_handling/fsm_aware.py b/tfw/internals/event_handling/fsm_aware.py similarity index 100% rename from lib/tfw/internals/event_handling/fsm_aware.py rename to tfw/internals/event_handling/fsm_aware.py diff --git a/lib/tfw/internals/event_handling/fsm_aware_event_handler.py b/tfw/internals/event_handling/fsm_aware_event_handler.py similarity index 100% rename from lib/tfw/internals/event_handling/fsm_aware_event_handler.py rename to tfw/internals/event_handling/fsm_aware_event_handler.py diff --git a/lib/tfw/internals/event_handling/test_event_handler.py b/tfw/internals/event_handling/test_event_handler.py similarity index 100% rename from lib/tfw/internals/event_handling/test_event_handler.py rename to tfw/internals/event_handling/test_event_handler.py diff --git a/lib/tfw/internals/inotify/__init__.py b/tfw/internals/inotify/__init__.py similarity index 100% rename from lib/tfw/internals/inotify/__init__.py rename to tfw/internals/inotify/__init__.py diff --git a/lib/tfw/internals/inotify/inotify.py b/tfw/internals/inotify/inotify.py similarity index 100% rename from lib/tfw/internals/inotify/inotify.py rename to tfw/internals/inotify/inotify.py diff --git a/lib/tfw/internals/inotify/test_inotify.py b/tfw/internals/inotify/test_inotify.py similarity index 100% rename from lib/tfw/internals/inotify/test_inotify.py rename to tfw/internals/inotify/test_inotify.py diff --git a/lib/tfw/internals/lazy.py b/tfw/internals/lazy.py similarity index 100% rename from lib/tfw/internals/lazy.py rename to tfw/internals/lazy.py diff --git a/lib/tfw/internals/networking/__init__.py b/tfw/internals/networking/__init__.py similarity index 100% rename from lib/tfw/internals/networking/__init__.py rename to tfw/internals/networking/__init__.py diff --git a/lib/tfw/internals/networking/event_handler_connector.py b/tfw/internals/networking/event_handler_connector.py similarity index 100% rename from lib/tfw/internals/networking/event_handler_connector.py rename to tfw/internals/networking/event_handler_connector.py diff --git a/lib/tfw/internals/networking/scope.py b/tfw/internals/networking/scope.py similarity index 100% rename from lib/tfw/internals/networking/scope.py rename to tfw/internals/networking/scope.py diff --git a/lib/tfw/internals/networking/serialization.py b/tfw/internals/networking/serialization.py similarity index 100% rename from lib/tfw/internals/networking/serialization.py rename to tfw/internals/networking/serialization.py diff --git a/lib/tfw/internals/networking/server_connector.py b/tfw/internals/networking/server_connector.py similarity index 100% rename from lib/tfw/internals/networking/server_connector.py rename to tfw/internals/networking/server_connector.py diff --git a/lib/tfw/internals/server/__init__.py b/tfw/internals/server/__init__.py similarity index 100% rename from lib/tfw/internals/server/__init__.py rename to tfw/internals/server/__init__.py diff --git a/lib/tfw/internals/server/zmq_websocket_router.py b/tfw/internals/server/zmq_websocket_router.py similarity index 100% rename from lib/tfw/internals/server/zmq_websocket_router.py rename to tfw/internals/server/zmq_websocket_router.py diff --git a/lib/tfw/logging.py b/tfw/logging.py similarity index 100% rename from lib/tfw/logging.py rename to tfw/logging.py diff --git a/lib/tfw/main/__init__.py b/tfw/main/__init__.py similarity index 100% rename from lib/tfw/main/__init__.py rename to tfw/main/__init__.py diff --git a/lib/tfw/main/event_handler_factory.py b/tfw/main/event_handler_factory.py similarity index 100% rename from lib/tfw/main/event_handler_factory.py rename to tfw/main/event_handler_factory.py diff --git a/lib/tfw/main/signal_handling.py b/tfw/main/signal_handling.py similarity index 100% rename from lib/tfw/main/signal_handling.py rename to tfw/main/signal_handling.py diff --git a/lib/tfw/main/tfw_connector.py b/tfw/main/tfw_connector.py similarity index 100% rename from lib/tfw/main/tfw_connector.py rename to tfw/main/tfw_connector.py diff --git a/lib/tfw/main/tfw_server.py b/tfw/main/tfw_server.py similarity index 100% rename from lib/tfw/main/tfw_server.py rename to tfw/main/tfw_server.py From f2b6123d4178cb5c9999fbd0a5294699210183b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Wed, 24 Jul 2019 16:32:57 +0200 Subject: [PATCH 16/18] Remove unnecessary newlines --- tfw/components/fsm/fsm_handler.py | 1 - tfw/components/ide/file_manager/test_file_manager.py | 2 +- tfw/components/ide/ide_handler.py | 1 - tfw/components/pipe_io/pipe_io_handler.py | 1 - tfw/components/process_management/process_handler.py | 1 - tfw/components/process_management/process_log_handler.py | 1 - tfw/components/snapshots/snapshot_handler.py | 1 - tfw/components/terminal/terminal_handler.py | 1 - tfw/config/envvars.py | 1 - tfw/main/tfw_server.py | 1 - 10 files changed, 1 insertion(+), 10 deletions(-) diff --git a/tfw/components/fsm/fsm_handler.py b/tfw/components/fsm/fsm_handler.py index 2dc163e..e86dee2 100644 --- a/tfw/components/fsm/fsm_handler.py +++ b/tfw/components/fsm/fsm_handler.py @@ -5,7 +5,6 @@ from tfw.internals.networking import Scope from .fsm_updater import FSMUpdater - LOG = logging.getLogger(__name__) diff --git a/tfw/components/ide/file_manager/test_file_manager.py b/tfw/components/ide/file_manager/test_file_manager.py index 380da0a..8f978d3 100644 --- a/tfw/components/ide/file_manager/test_file_manager.py +++ b/tfw/components/ide/file_manager/test_file_manager.py @@ -1,5 +1,4 @@ # pylint: disable=redefined-outer-name - from dataclasses import dataclass from secrets import token_urlsafe from os.path import join @@ -11,6 +10,7 @@ import pytest from .file_manager import FileManager + @dataclass class ManagerContext: folder: str diff --git a/tfw/components/ide/ide_handler.py b/tfw/components/ide/ide_handler.py index 225b80c..7f09247 100644 --- a/tfw/components/ide/ide_handler.py +++ b/tfw/components/ide/ide_handler.py @@ -5,7 +5,6 @@ from tfw.internals.inotify import InotifyObserver from .file_manager import FileManager - LOG = logging.getLogger(__name__) BUILD_ARTIFACTS = ( diff --git a/tfw/components/pipe_io/pipe_io_handler.py b/tfw/components/pipe_io/pipe_io_handler.py index 4f6a850..115b508 100644 --- a/tfw/components/pipe_io/pipe_io_handler.py +++ b/tfw/components/pipe_io/pipe_io_handler.py @@ -12,7 +12,6 @@ from contextlib import suppress from .pipe_io_server import PipeIOServer, terminate_process_on_failure - LOG = logging.getLogger(__name__) DEFAULT_PERMISSIONS = 0o600 diff --git a/tfw/components/process_management/process_handler.py b/tfw/components/process_management/process_handler.py index 54928fd..becd28d 100644 --- a/tfw/components/process_management/process_handler.py +++ b/tfw/components/process_management/process_handler.py @@ -5,7 +5,6 @@ from tfw.internals.networking import Scope from .supervisor import ProcessManager, ProcessLogManager - LOG = logging.getLogger(__name__) diff --git a/tfw/components/process_management/process_log_handler.py b/tfw/components/process_management/process_log_handler.py index 4ee084a..a7ed020 100644 --- a/tfw/components/process_management/process_log_handler.py +++ b/tfw/components/process_management/process_log_handler.py @@ -2,7 +2,6 @@ import logging from .log_inotify_observer import LogInotifyObserver - LOG = logging.getLogger(__name__) diff --git a/tfw/components/snapshots/snapshot_handler.py b/tfw/components/snapshots/snapshot_handler.py index 2ca9d28..c60c720 100644 --- a/tfw/components/snapshots/snapshot_handler.py +++ b/tfw/components/snapshots/snapshot_handler.py @@ -10,7 +10,6 @@ from tfw.internals.networking import Scope from .snapshot_provider import SnapshotProvider - LOG = logging.getLogger(__name__) diff --git a/tfw/components/terminal/terminal_handler.py b/tfw/components/terminal/terminal_handler.py index 2cbdff4..a0a5f0c 100644 --- a/tfw/components/terminal/terminal_handler.py +++ b/tfw/components/terminal/terminal_handler.py @@ -3,7 +3,6 @@ import logging from .history_monitor import BashMonitor from .terminado_mini_server import TerminadoMiniServer - LOG = logging.getLogger(__name__) diff --git a/tfw/config/envvars.py b/tfw/config/envvars.py index 1e4c89a..dcf767d 100644 --- a/tfw/config/envvars.py +++ b/tfw/config/envvars.py @@ -1,5 +1,4 @@ from .lazy_environment import LazyEnvironment - TFWENV = LazyEnvironment('TFW_', 'tfwenvtuple').environment TAOENV = LazyEnvironment('AVATAO_', 'taoenvtuple').environment diff --git a/tfw/main/tfw_server.py b/tfw/main/tfw_server.py index 22d216f..4cc1c5e 100644 --- a/tfw/main/tfw_server.py +++ b/tfw/main/tfw_server.py @@ -6,7 +6,6 @@ from tfw.internals.networking import EventHandlerConnector from tfw.internals.server import ZMQWebSocketRouter from tfw.config import TFWENV - LOG = logging.getLogger(__name__) From 42f959878f14727bf859d4d4ac0ee6b6f413f684 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Wed, 24 Jul 2019 16:47:03 +0200 Subject: [PATCH 17/18] Add signal handling to tfw_server.py --- supervisor/tfw_server.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/supervisor/tfw_server.py b/supervisor/tfw_server.py index f3ad4be..eccd753 100644 --- a/supervisor/tfw_server.py +++ b/supervisor/tfw_server.py @@ -2,7 +2,7 @@ from sys import stderr from tornado.ioloop import IOLoop -from tfw.main import TFWServer +from tfw.main import TFWServer, setup_signal_handlers from tfw.config import TFWENV from tfw.logging import Log, Logger, LogFormatter, VerboseLogFormatter @@ -13,4 +13,6 @@ if __name__ == '__main__': Log(TFWENV.LOGFILE, VerboseLogFormatter()) ]).start() TFWServer().listen() + + setup_signal_handlers() IOLoop.instance().start() From 3fca5552519db222ec82e5639ac672ad884631eb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=B3f=20T=C3=B3th?= Date: Wed, 24 Jul 2019 17:22:08 +0200 Subject: [PATCH 18/18] Move TFWRouter to separate file --- tfw/internals/server/tfw_router.py | 22 +++++++++++++++++++ tfw/internals/server/zmq_websocket_router.py | 23 +------------------- 2 files changed, 23 insertions(+), 22 deletions(-) create mode 100644 tfw/internals/server/tfw_router.py diff --git a/tfw/internals/server/tfw_router.py b/tfw/internals/server/tfw_router.py new file mode 100644 index 0000000..c2a18ab --- /dev/null +++ b/tfw/internals/server/tfw_router.py @@ -0,0 +1,22 @@ +from tfw.internals.networking import Scope + + +class TFWRouter: + def __init__(self, send_to_zmq, send_to_websockets): + self.send_to_zmq = send_to_zmq + self.send_to_websockets = send_to_websockets + + def route(self, message): + scope = Scope(message.pop('scope', 'zmq')) + + routing_table = { + Scope.ZMQ: self.send_to_zmq, + Scope.WEBSOCKET: self.send_to_websockets, + Scope.BROADCAST: self.broadcast + } + action = routing_table[scope] + action(message) + + def broadcast(self, message): + self.send_to_zmq(message) + self.send_to_websockets(message) diff --git a/tfw/internals/server/zmq_websocket_router.py b/tfw/internals/server/zmq_websocket_router.py index cdafc2f..3f5e7fc 100644 --- a/tfw/internals/server/zmq_websocket_router.py +++ b/tfw/internals/server/zmq_websocket_router.py @@ -3,7 +3,7 @@ import logging from tornado.websocket import WebSocketHandler -from tfw.internals.networking import Scope +from .tfw_router import TFWRouter LOG = logging.getLogger(__name__) @@ -46,24 +46,3 @@ class ZMQWebSocketRouter(WebSocketHandler): # much secure, very cors, wow def check_origin(self, origin): return True - - -class TFWRouter: - def __init__(self, send_to_zmq, send_to_websockets): - self.send_to_zmq = send_to_zmq - self.send_to_websockets = send_to_websockets - - def route(self, message): - scope = Scope(message.pop('scope', 'zmq')) - - routing_table = { - Scope.ZMQ: self.send_to_zmq, - Scope.WEBSOCKET: self.send_to_websockets, - Scope.BROADCAST: self.broadcast - } - action = routing_table[scope] - action(message) - - def broadcast(self, message): - self.send_to_zmq(message) - self.send_to_websockets(message)