Compare commits

..
11 changed files with 33 additions and 26 deletions
+5 -4
View File
@@ -11,7 +11,8 @@ RUN curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
libzmq5 \ libzmq5 \
nginx \ nginx \
gettext-base &&\ gettext-base &&\
rm -rf /var/lib/apt/lists/* rm -rf /var/lib/apt/lists/* &&\
ln -sf /bin/bash /bin/sh
COPY requirements.txt /tmp COPY requirements.txt /tmp
RUN pip3 install -r /tmp/requirements.txt RUN pip3 install -r /tmp/requirements.txt
@@ -26,7 +27,7 @@ ENV TFW_PUBLIC_PORT=8888 \
EXPOSE ${TFW_PUBLIC_PORT} EXPOSE ${TFW_PUBLIC_PORT}
ENV PYTHONPATH="/usr/local/lib/" \ ENV PYTHONPATH="/usr/local/lib" \
TFW_SUPERVISOR_HTTP_URI="http://localhost:${TFW_SUPERVISOR_HTTP_PORT}" \ TFW_SUPERVISOR_HTTP_URI="http://localhost:${TFW_SUPERVISOR_HTTP_PORT}" \
TFW_SUPERVISORD_CONF="/etc/supervisor/supervisord.conf" \ TFW_SUPERVISORD_CONF="/etc/supervisor/supervisord.conf" \
TFW_SUPERVISORD_COMPONENTS="/etc/supervisor/conf" \ TFW_SUPERVISORD_COMPONENTS="/etc/supervisor/conf" \
@@ -49,8 +50,8 @@ COPY nginx/default.conf ${TFW_NGINX_DEFAULT}
COPY nginx/components/ ${TFW_NGINX_COMPONENTS} COPY nginx/components/ ${TFW_NGINX_COMPONENTS}
COPY lib LICENSE ${TFW_LIB_DIR} COPY lib LICENSE ${TFW_LIB_DIR}
RUN for dir in "${TFW_LIB_DIR}" "/etc/nginx" "/etc/supervisor"; do \ RUN for dir in "${TFW_LIB_DIR}"/{tfw,tao,envvars.py} "/etc/nginx" "/etc/supervisor"; do \
chown -R root:root "$dir" && chmod -R 700 "$dir"; \ chown -R root:root "$dir" && chmod -R 700 "$dir"; \
done done
ONBUILD ARG BUILD_CONTEXT="solvable" ONBUILD ARG BUILD_CONTEXT="solvable"
+1 -1
View File
@@ -58,7 +58,7 @@ Don't worry, we are not too fond of rules around these parts.
The TFW message format: The TFW message format:
```json ```text
{ {
"key: "some identifier used for addressing", "key: "some identifier used for addressing",
"data": "data":
Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 40 KiB

+1 -1
View File
@@ -4,6 +4,6 @@
from .directory_monitoring_event_handler import DirectoryMonitoringEventHandler from .directory_monitoring_event_handler import DirectoryMonitoringEventHandler
from .process_managing_event_handler import ProcessManagingEventHandler from .process_managing_event_handler import ProcessManagingEventHandler
from .terminado_event_handler import TerminadoEventHandler from .terminado_event_handler import TerminadoEventHandler
from .webide_event_handler import WebideEventHandler from .ide_event_handler import IdeEventHandler
from .history_monitor import HistoryMonitor, BashMonitor, GDBMonitor from .history_monitor import HistoryMonitor, BashMonitor, GDBMonitor
from .terminal_commands import TerminalCommands from .terminal_commands import TerminalCommands
+3 -3
View File
@@ -17,7 +17,7 @@ LOG = logging.getLogger(__name__)
class DirectoryMonitor(ObserverMixin): class DirectoryMonitor(ObserverMixin):
def __init__(self, directory): def __init__(self, directory):
ObserverMixin.__init__(self) ObserverMixin.__init__(self)
self.eventhandler = WebideReloadWatchdogEventHandler() self.eventhandler = IdeReloadWatchdogEventHandler()
self.observer.schedule(self.eventhandler, directory, recursive=True) self.observer.schedule(self.eventhandler, directory, recursive=True)
self.pause, self.resume = self.eventhandler.pause, self.eventhandler.resume self.pause, self.resume = self.eventhandler.pause, self.eventhandler.resume
@@ -42,7 +42,7 @@ class DirectoryMonitor(ObserverMixin):
self.directorymonitor.resume() self.directorymonitor.resume()
class WebideReloadWatchdogEventHandler(FileSystemWatchdogEventHandler): class IdeReloadWatchdogEventHandler(FileSystemWatchdogEventHandler):
def __init__(self): def __init__(self):
super().__init__() super().__init__()
self.uplink = ServerUplinkConnector() self.uplink = ServerUplinkConnector()
@@ -63,7 +63,7 @@ class WebideReloadWatchdogEventHandler(FileSystemWatchdogEventHandler):
self.ignore = self.ignore - 1 self.ignore = self.ignore - 1
return return
LOG.debug(event) LOG.debug(event)
self.uplink.send({'key': 'webide', self.uplink.send({'key': 'ide',
'data': {'command': 'reload'}}) 'data': {'command': 'reload'}})
@@ -40,9 +40,9 @@ class FileManager: # pylint: disable=too-many-instance-attributes
@workdir.setter @workdir.setter
def workdir(self, directory): def workdir(self, directory):
if not exists(directory) or not isdir(directory): if not exists(directory) or not isdir(directory):
raise EnvironmentError('"{}" is not a directory!'.format(directory)) raise EnvironmentError(f'"{directory}" is not a directory!')
if not self._is_in_whitelisted_dir(directory): if not self._is_in_whitelisted_dir(directory):
raise EnvironmentError('Directory "{}" is not in whitelist!'.format(directory)) raise EnvironmentError(f'Directory "{directory}" is not in whitelist!')
self._workdir = directory self._workdir = directory
@property @property
@@ -91,7 +91,7 @@ class FileManager: # pylint: disable=too-many-instance-attributes
return relpath(self._filepath(filename), start=self._workdir) return relpath(self._filepath(filename), start=self._workdir)
class WebideEventHandler(EventHandlerBase, MonitorManagerMixin): class IdeEventHandler(EventHandlerBase, MonitorManagerMixin):
# pylint: disable=too-many-arguments # pylint: disable=too-many-arguments
""" """
Event handler implementing the backend of our browser based IDE. Event handler implementing the backend of our browser based IDE.
@@ -141,7 +141,8 @@ class WebideEventHandler(EventHandlerBase, MonitorManagerMixin):
""" """
Overwrites a file with the desired string. Overwrites a file with the desired string.
:param data['content']: string containing the desired file contents :param data: TFW message data containing keys:
|-string: containing the desired file contents
""" """
self.monitor.ignore = self.monitor.ignore + 1 self.monitor.ignore = self.monitor.ignore + 1
try: try:
@@ -155,7 +156,8 @@ class WebideEventHandler(EventHandlerBase, MonitorManagerMixin):
""" """
Selects a file from the current directory. Selects a file from the current directory.
:param data['filename']: name of file to select relative to the current directory :param data: TFW message data containing keys:
|-filename: name of file to select relative to the current directory
""" """
try: try:
self.filemanager.filename = data['filename'] self.filemanager.filename = data['filename']
@@ -167,9 +169,10 @@ class WebideEventHandler(EventHandlerBase, MonitorManagerMixin):
""" """
Select a new working directory to display files from. Select a new working directory to display files from.
:param data['directory']: absolute path of diretory to select. :param data: TFW message data containing keys:
must be a path whitelisted in |-directory: absolute path of diretory to select.
self.allowed_directories must be a path whitelisted in
self.allowed_directories
""" """
try: try:
self.filemanager.workdir = data['directory'] self.filemanager.workdir = data['directory']
@@ -187,7 +190,8 @@ class WebideEventHandler(EventHandlerBase, MonitorManagerMixin):
""" """
Overwrite list of excluded files Overwrite list of excluded files
:param data['exclude']: list of filename patterns to be excluded, e.g.: ["*.pyc", "*.o"] :param data: TFW message data containing keys:
|-exclude: list of filename patterns to be excluded, e.g.: ["*.pyc", "*.o"]
""" """
try: try:
self.filemanager.exclude = list(data['exclude']) self.filemanager.exclude = list(data['exclude'])
@@ -54,7 +54,8 @@ class TerminadoEventHandler(EventHandlerBase):
Writes a string to the terminal session (on the pty level). Writes a string to the terminal session (on the pty level).
Useful for pre-typing and executing commands for the user. Useful for pre-typing and executing commands for the user.
:param data['shellcmd']: command to be written to the pty :param data: TFW message data containing keys:
|-shellcmd: command to be written to the pty
""" """
self.terminado_server.pty.write(data['shellcmd']) self.terminado_server.pty.write(data['shellcmd'])
@@ -62,7 +63,8 @@ class TerminadoEventHandler(EventHandlerBase):
""" """
Reads the history of commands executed. Reads the history of commands executed.
:param data['count']: the number of history elements to return :param data: TFW message data containing keys:
|-count: the number of history elements to return
:return: message with list of commands in data['history'] :return: message with list of commands in data['history']
""" """
data['count'] = int(data.get('count', 1)) data['count'] = int(data.get('count', 1))
+1 -1
View File
@@ -13,6 +13,6 @@ class LinearFSM(FSMBase):
""" """
def __init__(self, number_of_steps): def __init__(self, number_of_steps):
self.states = list(map(str, range(number_of_steps))) self.states = list(map(str, range(number_of_steps)))
self.transitions = [{'trigger': 'step_{}'.format(int(index)+1), 'source': index, 'dest': str(int(index)+1)} self.transitions = [{'trigger': f'step_{int(index)+1}', 'source': index, 'dest': str(int(index)+1)}
for index in self.states[:-1]] for index in self.states[:-1]]
super(LinearFSM, self).__init__() super(LinearFSM, self).__init__()
+1 -1
View File
@@ -12,7 +12,7 @@ class ControllerConnector(ZMQConnectorBase):
def __init__(self, zmq_context=None): def __init__(self, zmq_context=None):
super(ControllerConnector, self).__init__(zmq_context) super(ControllerConnector, self).__init__(zmq_context)
self._zmq_rep_socket = self._zmq_context.socket(zmq.REP) self._zmq_rep_socket = self._zmq_context.socket(zmq.REP)
self._zmq_rep_socket.connect('tcp://localhost:{}'.format(TFWENV.CONTROLLER_PORT)) self._zmq_rep_socket.connect(f'tcp://localhost:{TFWENV.CONTROLLER_PORT}')
self._zmq_rep_stream = ZMQStream(self._zmq_rep_socket) self._zmq_rep_stream = ZMQStream(self._zmq_rep_socket)
self.register_callback = self._zmq_rep_stream.on_recv_stream self.register_callback = self._zmq_rep_stream.on_recv_stream
@@ -15,7 +15,7 @@ class ServerDownlinkConnector(ZMQConnectorBase):
def __init__(self, zmq_context=None): def __init__(self, zmq_context=None):
super(ServerDownlinkConnector, self).__init__(zmq_context) super(ServerDownlinkConnector, self).__init__(zmq_context)
self._zmq_sub_socket = self._zmq_context.socket(zmq.SUB) self._zmq_sub_socket = self._zmq_context.socket(zmq.SUB)
self._zmq_sub_socket.connect('tcp://localhost:{}'.format(TFWENV.PUBLISHER_PORT)) self._zmq_sub_socket.connect(f'tcp://localhost:{TFWENV.PUBLISHER_PORT}')
self._zmq_sub_stream = ZMQStream(self._zmq_sub_socket) self._zmq_sub_stream = ZMQStream(self._zmq_sub_socket)
self.subscribe = partial(self._zmq_sub_socket.setsockopt_string, zmq.SUBSCRIBE) self.subscribe = partial(self._zmq_sub_socket.setsockopt_string, zmq.SUBSCRIBE)
@@ -30,7 +30,7 @@ class ServerUplinkConnector(ZMQConnectorBase):
def __init__(self, zmq_context=None): def __init__(self, zmq_context=None):
super(ServerUplinkConnector, self).__init__(zmq_context) super(ServerUplinkConnector, self).__init__(zmq_context)
self._zmq_push_socket = self._zmq_context.socket(zmq.PUSH) self._zmq_push_socket = self._zmq_context.socket(zmq.PUSH)
self._zmq_push_socket.connect('tcp://localhost:{}'.format(TFWENV.RECEIVER_PORT)) self._zmq_push_socket.connect(f'tcp://localhost:{TFWENV.RECEIVER_PORT}')
def send_to_eventhandler(self, message): def send_to_eventhandler(self, message):
""" """
@@ -16,7 +16,7 @@ class EventHandlerDownlinkConnector(ZMQConnectorBase):
super(EventHandlerDownlinkConnector, self).__init__(zmq_context) super(EventHandlerDownlinkConnector, self).__init__(zmq_context)
self._zmq_pull_socket = self._zmq_context.socket(zmq.PULL) self._zmq_pull_socket = self._zmq_context.socket(zmq.PULL)
self._zmq_pull_stream = ZMQStream(self._zmq_pull_socket) self._zmq_pull_stream = ZMQStream(self._zmq_pull_socket)
address = 'tcp://*:{}'.format(TFWENV.RECEIVER_PORT) address = f'tcp://*:{TFWENV.RECEIVER_PORT}'
self._zmq_pull_socket.bind(address) self._zmq_pull_socket.bind(address)
LOG.debug('Pull socket bound to %s', address) LOG.debug('Pull socket bound to %s', address)
@@ -25,7 +25,7 @@ class EventHandlerUplinkConnector(ZMQConnectorBase):
def __init__(self, zmq_context=None): def __init__(self, zmq_context=None):
super(EventHandlerUplinkConnector, self).__init__(zmq_context) super(EventHandlerUplinkConnector, self).__init__(zmq_context)
self._zmq_pub_socket = self._zmq_context.socket(zmq.PUB) self._zmq_pub_socket = self._zmq_context.socket(zmq.PUB)
address = 'tcp://*:{}'.format(TFWENV.PUBLISHER_PORT) address = f'tcp://*:{TFWENV.PUBLISHER_PORT}'
self._zmq_pub_socket.bind(address) self._zmq_pub_socket.bind(address)
LOG.debug('Pub socket bound to %s', address) LOG.debug('Pub socket bound to %s', address)