Merge pull request #21 from avatao-content/platform_fixes

Add platform fixes to TFW and implement Geri's feature requests
This commit is contained in:
Bokros Bálint 2018-03-14 14:37:20 +01:00 committed by GitHub
commit abeb12858e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 95 additions and 51 deletions

View File

@ -34,10 +34,9 @@ RUN curl -fSL -o pyenv-installer ${PYENV_INSTALLER_URL} &&\
pip install -r /tmp/requirements.txt pip install -r /tmp/requirements.txt
USER root USER root
WORKDIR /data/
COPY src/frontend /data/ COPY src/frontend /data/
RUN yarn install --frozen-lockfile RUN cd /data && yarn install --frozen-lockfile
RUN yarn build --no-progress RUN cd /data && yarn build --no-progress
ENV TFW_PUBLIC_PORT=8888 \ ENV TFW_PUBLIC_PORT=8888 \
TFW_WEB_PORT=4242 \ TFW_WEB_PORT=4242 \
@ -55,7 +54,8 @@ 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" \
TFW_NGINX_CONF="/etc/nginx/sites-enabled/default" \ TFW_NGINX_CONF="/etc/nginx/nginx.conf" \
TFW_NGINX_DEFAULT="/etc/nginx/sites-enabled/default" \
TFW_NGINX_COMPONENTS="/etc/nginx/components" \ TFW_NGINX_COMPONENTS="/etc/nginx/components" \
TFW_LIB_DIR="/usr/local/lib/" \ TFW_LIB_DIR="/usr/local/lib/" \
TFW_CONTROLLER_DIR="/srv/controller" \ TFW_CONTROLLER_DIR="/srv/controller" \
@ -74,17 +74,18 @@ RUN echo "shopt -s cmdhist\n" \
>> /home/${AVATAO_USER}/.bashrc >> /home/${AVATAO_USER}/.bashrc
COPY nginx/nginx.conf ${TFW_NGINX_CONF} COPY nginx/nginx.conf ${TFW_NGINX_CONF}
COPY nginx/default.conf ${TFW_NGINX_DEFAULT}
COPY nginx/components/ ${TFW_NGINX_COMPONENTS} COPY nginx/components/ ${TFW_NGINX_COMPONENTS}
RUN chown -R ${AVATAO_USER} /var/log/nginx /var/lib/nginx &&\ RUN chown -R ${AVATAO_USER} /var/log/nginx /var/lib/nginx &&\
sed -i 's#pid /run/nginx.pid;#pid /tmp/nginx.pid;#g' /etc/nginx/nginx.conf &&\ for f in "${TFW_NGINX_DEFAULT}" ${TFW_NGINX_COMPONENTS}/*.conf; do \
for f in "${TFW_NGINX_CONF}" ${TFW_NGINX_COMPONENTS}/*.conf; do \ envsubst "$(printenv | cut -d= -f1 | grep TFW_ | sed -e 's/^/$/g')" < $f > $f~ && mv $f~ $f ;\
envsubst "$(printenv | cut -d= -f1 | grep TFW_ | sed -e 's/^/$/g')" < $f > $f ;\
done done
COPY supervisor/supervisord.conf ${TFW_SUPERVISORD_CONF} COPY supervisor/supervisord.conf ${TFW_SUPERVISORD_CONF}
COPY supervisor/components/ ${TFW_SUPERVISORD_COMPONENTS} COPY supervisor/components/ ${TFW_SUPERVISORD_COMPONENTS}
COPY lib ${TFW_LIB_DIR} COPY lib ${TFW_LIB_DIR}
COPY src/controller ${TFW_CONTROLLER_DIR} COPY src/controller ${TFW_CONTROLLER_DIR}
RUN mv /data/dist ${TFW_FRONTEND_DIR} && rm -rf /data
### TFW internals ^ ### DEMO v ############################################################### ### TFW internals ^ ### DEMO v ###############################################################
@ -93,17 +94,17 @@ ENV TFW_APP_DIR="/srv/app" \
TFW_WEBIDE_WD="/home/${AVATAO_USER}/workdir" \ TFW_WEBIDE_WD="/home/${AVATAO_USER}/workdir" \
TFW_TERMINADO_WD="/home/${AVATAO_USER}/workdir" TFW_TERMINADO_WD="/home/${AVATAO_USER}/workdir"
RUN mv /data/dist ${TFW_FRONTEND_DIR}
COPY src/demo ${TFW_APP_DIR}/ COPY src/demo ${TFW_APP_DIR}/
COPY src/demo/source_code_server/server.py ${TFW_LOGIN_APP_DIR}/ COPY src/demo/source_code_server/server.py ${TFW_LOGIN_APP_DIR}/
COPY src/demo/source_code_server/users.db ${TFW_LOGIN_APP_DIR}/ COPY src/demo/source_code_server/users.db ${TFW_LOGIN_APP_DIR}/
COPY src/demo/source_code_server/login_component.py ${TFW_WEBIDE_WD}/ COPY src/demo/source_code_server/login_component.py ${TFW_WEBIDE_WD}/
RUN chown -R ${AVATAO_USER} ${TFW_WEBIDE_WD} && chmod -R 755 ${TFW_WEBIDE_WD} RUN chown -R ${AVATAO_USER} ${TFW_WEBIDE_WD} &&\
chmod -R 755 ${TFW_WEBIDE_WD}
USER ${AVATAO_USER} USER ${AVATAO_USER}
VOLUME ["/etc/nginx", "/home/${AVATAO_USER}", "/var/lib/nginx", "/var/log/nginx"]
WORKDIR /home/${AVATAO_USER} WORKDIR /home/${AVATAO_USER}
CMD . "$HOME/.pyenvrc" && exec supervisord --nodaemon CMD . "$HOME/.pyenvrc" && exec supervisord --nodaemon

View File

@ -106,7 +106,7 @@ class SourceCodeEventHandler(TriggerlessEventHandler):
except IndexError: except IndexError:
data['content'] = 'No files in this directory :(' data['content'] = 'No files in this directory :('
except EnvironmentError: except EnvironmentError:
log.exception('Failed to select directory "{}"'.format(data['directory'])) log.error('Failed to select directory "{}"'.format(data['directory']))
return data return data
def attach_fileinfo(self, data): def attach_fileinfo(self, data):

View File

@ -1,18 +1,7 @@
from itertools import cycle
from tfw.networking.serialization import deserialize_all from tfw.networking.serialization import deserialize_all
from tfw.networking.event_handlers.server_connector import ServerConnector from tfw.networking.event_handlers.server_connector import ServerConnector
def cenator():
yield from [
'**Your time is up**',
'`My time is now`',
'_You can\'t see me_',
'My time is now'
]
class EventHandlerBase: class EventHandlerBase:
def __init__(self, key): def __init__(self, key):
self.server_connector = ServerConnector() self.server_connector = ServerConnector()
@ -21,13 +10,9 @@ class EventHandlerBase:
self.subscribe(self.key) self.subscribe(self.key)
self.subscribe('reset') self.subscribe('reset')
self.server_connector.register_callback(self.event_handler_callback) self.server_connector.register_callback(self.event_handler_callback)
self.cenerator = cycle(cenator())
def event_handler_callback(self, msg_parts): def event_handler_callback(self, msg_parts):
key, message = deserialize_all(*msg_parts) key, message = deserialize_all(*msg_parts)
from .message_sender import MessageSender
ms = MessageSender()
ms.send('avataobot', next(self.cenerator))
response = self.dispatch_handling(key, message) response = self.dispatch_handling(key, message)
if response is None: return if response is None: return
self.server_connector.send(key, response) self.server_connector.send(key, response)

View File

@ -25,6 +25,10 @@ class ServerUplinkConnector(ZMQConnectorBase):
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('tcp://localhost:{}'.format(tfwenv.RECEIVER_PORT))
def send_to_eventhandler(self, key, response):
response['data']['key'] = key
self.send('mirror', response)
def send(self, key, response): def send(self, key, response):
response['key'] = key response['key'] = key
self._zmq_push_socket.send_multipart(serialize_all(key, response)) self._zmq_push_socket.send_multipart(serialize_all(key, response))

View File

@ -21,12 +21,23 @@ class ZMQWebSocketHandler(WebSocketHandler):
log.debug('WebSocket connection initiated') log.debug('WebSocket connection initiated')
self._event_handler_connector.register_callback(self.zmq_callback) self._event_handler_connector.register_callback(self.zmq_callback)
@staticmethod @classmethod
def zmq_callback(msg_parts): def zmq_callback(cls, msg_parts):
keyhandlers = {'mirror': cls.mirror}
key, data = deserialize_all(*msg_parts) key, data = deserialize_all(*msg_parts)
log.debug('Received on pull socket: {}'.format(data)) log.debug('Received on pull socket: {}'.format(data))
for instance in ZMQWebSocketHandler.instances: if key not in keyhandlers:
for instance in cls.instances:
instance.write_message(data) instance.write_message(data)
else:
try: keyhandlers[key](data['data'])
except KeyError: log.error('Invalid mirror message format! Ignoring.')
@classmethod
def mirror(cls, data):
key = data['key']
cls._event_handler_connector.send_message({'data': data}, key)
def on_message(self, message): def on_message(self, message):
log.debug('Received on WebSocket: {}'.format(message)) log.debug('Received on WebSocket: {}'.format(message))

22
nginx/default.conf Normal file
View File

@ -0,0 +1,22 @@
server {
listen ${TFW_PUBLIC_PORT};
server_name localhost;
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
location = /ws {
proxy_pass http://127.0.0.1:${TFW_WEB_PORT};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
}
include ${TFW_NGINX_COMPONENTS}/*.conf;
location / {
index index.html;
try_files $uri $uri/ /index.html =404;
root ${TFW_FRONTEND_DIR};
}
}

View File

@ -1,21 +1,24 @@
server { worker_processes auto;
listen ${TFW_PUBLIC_PORT}; pid /tmp/nginx.pid;
server_name localhost;
proxy_connect_timeout 7d;
proxy_send_timeout 7d;
proxy_read_timeout 7d;
location = /ws { events
proxy_pass http://127.0.0.1:${TFW_WEB_PORT}; {
proxy_http_version 1.1; worker_connections 1024;
proxy_set_header Upgrade $http_upgrade; }
proxy_set_header Connection "Upgrade";
} http
{
include ${TFW_NGINX_COMPONENTS}/*.conf; sendfile on;
tcp_nopush on;
location / { tcp_nodelay on;
root ${TFW_FRONTEND_DIR}; keepalive_timeout 65;
try_files $uri $uri/ index.html;
} include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /dev/stdout;
error_log /dev/stderr;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
} }

View File

@ -4,14 +4,32 @@ from tfw.components.source_code_event_handler import SourceCodeEventHandler
from tfw.components.terminado_event_handler import TerminadoEventHandler from tfw.components.terminado_event_handler import TerminadoEventHandler
from tfw.components.process_managing_event_handler import ProcessManagingEventHandler from tfw.components.process_managing_event_handler import ProcessManagingEventHandler
from tfw.config import tfwenv from tfw.config import tfwenv
from tfw.message_sender import MessageSender
from tfw.networking.event_handlers.server_connector import ServerUplinkConnector
from tfw.config.logs import logging from tfw.config.logs import logging
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
def cenator(history):
log.debug('User executed command: "{}"'.format(history[-1]))
MessageSender().send('JOHN CENA', 'You\'ve executed "{}"'.format(history[-1]))
def selectdir(history):
try:
cmd = history[-1].split()
if cmd[0] == 'selectdir':
ServerUplinkConnector().send_to_eventhandler('webide',
{'data': {'command': 'selectdir',
'directory': cmd[1]}})
except Exception:
log.exception('Selectdir failed!')
if __name__ == '__main__': if __name__ == '__main__':
ide = SourceCodeEventHandler(key='webide', directory=tfwenv.WEBIDE_WD, exclude=['__pycache__']) ide = SourceCodeEventHandler(key='webide', directory=tfwenv.WEBIDE_WD, exclude=['__pycache__'])
terminado = TerminadoEventHandler(key='shell') terminado = TerminadoEventHandler(key='shell')
terminado.historymonitor.subscribe_callback(callback=lambda hist: log.debug('User executed command: "{}"'.format(hist[-1]))) terminado.historymonitor.subscribe_callback(cenator)
terminado.historymonitor.subscribe_callback(selectdir)
processmanager = ProcessManagingEventHandler(key='processmanager', dirmonitor=ide.monitor) processmanager = ProcessManagingEventHandler(key='processmanager', dirmonitor=ide.monitor)
eventhandlers = {ide, terminado, processmanager} eventhandlers = {ide, terminado, processmanager}