mirror of
https://github.com/avatao-content/baseimage-tutorial-framework
synced 2024-11-05 14:31:21 +00:00
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:
commit
abeb12858e
23
Dockerfile
23
Dockerfile
@ -34,10 +34,9 @@ RUN curl -fSL -o pyenv-installer ${PYENV_INSTALLER_URL} &&\
|
||||
pip install -r /tmp/requirements.txt
|
||||
|
||||
USER root
|
||||
WORKDIR /data/
|
||||
COPY src/frontend /data/
|
||||
RUN yarn install --frozen-lockfile
|
||||
RUN yarn build --no-progress
|
||||
RUN cd /data && yarn install --frozen-lockfile
|
||||
RUN cd /data && yarn build --no-progress
|
||||
|
||||
ENV TFW_PUBLIC_PORT=8888 \
|
||||
TFW_WEB_PORT=4242 \
|
||||
@ -55,7 +54,8 @@ ENV PYTHONPATH="/usr/local/lib/" \
|
||||
TFW_SUPERVISOR_HTTP_URI="http://localhost:${TFW_SUPERVISOR_HTTP_PORT}" \
|
||||
TFW_SUPERVISORD_CONF="/etc/supervisor/supervisord.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_LIB_DIR="/usr/local/lib/" \
|
||||
TFW_CONTROLLER_DIR="/srv/controller" \
|
||||
@ -74,17 +74,18 @@ RUN echo "shopt -s cmdhist\n" \
|
||||
>> /home/${AVATAO_USER}/.bashrc
|
||||
|
||||
COPY nginx/nginx.conf ${TFW_NGINX_CONF}
|
||||
COPY nginx/default.conf ${TFW_NGINX_DEFAULT}
|
||||
COPY nginx/components/ ${TFW_NGINX_COMPONENTS}
|
||||
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_CONF}" ${TFW_NGINX_COMPONENTS}/*.conf; do \
|
||||
envsubst "$(printenv | cut -d= -f1 | grep TFW_ | sed -e 's/^/$/g')" < $f > $f ;\
|
||||
RUN chown -R ${AVATAO_USER} /var/log/nginx /var/lib/nginx &&\
|
||||
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
|
||||
|
||||
COPY supervisor/supervisord.conf ${TFW_SUPERVISORD_CONF}
|
||||
COPY supervisor/components/ ${TFW_SUPERVISORD_COMPONENTS}
|
||||
COPY lib ${TFW_LIB_DIR}
|
||||
COPY src/controller ${TFW_CONTROLLER_DIR}
|
||||
RUN mv /data/dist ${TFW_FRONTEND_DIR} && rm -rf /data
|
||||
|
||||
### TFW internals ^ ### DEMO v ###############################################################
|
||||
|
||||
@ -93,17 +94,17 @@ ENV TFW_APP_DIR="/srv/app" \
|
||||
TFW_WEBIDE_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/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/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}
|
||||
VOLUME ["/etc/nginx", "/home/${AVATAO_USER}", "/var/lib/nginx", "/var/log/nginx"]
|
||||
WORKDIR /home/${AVATAO_USER}
|
||||
|
||||
CMD . "$HOME/.pyenvrc" && exec supervisord --nodaemon
|
||||
|
@ -106,7 +106,7 @@ class SourceCodeEventHandler(TriggerlessEventHandler):
|
||||
except IndexError:
|
||||
data['content'] = 'No files in this directory :('
|
||||
except EnvironmentError:
|
||||
log.exception('Failed to select directory "{}"'.format(data['directory']))
|
||||
log.error('Failed to select directory "{}"'.format(data['directory']))
|
||||
return data
|
||||
|
||||
def attach_fileinfo(self, data):
|
||||
|
@ -1,18 +1,7 @@
|
||||
from itertools import cycle
|
||||
|
||||
from tfw.networking.serialization import deserialize_all
|
||||
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:
|
||||
def __init__(self, key):
|
||||
self.server_connector = ServerConnector()
|
||||
@ -21,13 +10,9 @@ class EventHandlerBase:
|
||||
self.subscribe(self.key)
|
||||
self.subscribe('reset')
|
||||
self.server_connector.register_callback(self.event_handler_callback)
|
||||
self.cenerator = cycle(cenator())
|
||||
|
||||
def event_handler_callback(self, 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)
|
||||
if response is None: return
|
||||
self.server_connector.send(key, response)
|
||||
|
@ -25,6 +25,10 @@ class ServerUplinkConnector(ZMQConnectorBase):
|
||||
self._zmq_push_socket = self._zmq_context.socket(zmq.PUSH)
|
||||
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):
|
||||
response['key'] = key
|
||||
self._zmq_push_socket.send_multipart(serialize_all(key, response))
|
||||
|
@ -21,12 +21,23 @@ class ZMQWebSocketHandler(WebSocketHandler):
|
||||
log.debug('WebSocket connection initiated')
|
||||
self._event_handler_connector.register_callback(self.zmq_callback)
|
||||
|
||||
@staticmethod
|
||||
def zmq_callback(msg_parts):
|
||||
@classmethod
|
||||
def zmq_callback(cls, msg_parts):
|
||||
keyhandlers = {'mirror': cls.mirror}
|
||||
|
||||
key, data = deserialize_all(*msg_parts)
|
||||
log.debug('Received on pull socket: {}'.format(data))
|
||||
for instance in ZMQWebSocketHandler.instances:
|
||||
instance.write_message(data)
|
||||
if key not in keyhandlers:
|
||||
for instance in cls.instances:
|
||||
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):
|
||||
log.debug('Received on WebSocket: {}'.format(message))
|
||||
|
22
nginx/default.conf
Normal file
22
nginx/default.conf
Normal 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};
|
||||
}
|
||||
}
|
@ -1,21 +1,24 @@
|
||||
server {
|
||||
listen ${TFW_PUBLIC_PORT};
|
||||
server_name localhost;
|
||||
proxy_connect_timeout 7d;
|
||||
proxy_send_timeout 7d;
|
||||
proxy_read_timeout 7d;
|
||||
worker_processes auto;
|
||||
pid /tmp/nginx.pid;
|
||||
|
||||
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 / {
|
||||
root ${TFW_FRONTEND_DIR};
|
||||
try_files $uri $uri/ index.html;
|
||||
}
|
||||
events
|
||||
{
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http
|
||||
{
|
||||
sendfile on;
|
||||
tcp_nopush on;
|
||||
tcp_nodelay on;
|
||||
keepalive_timeout 65;
|
||||
|
||||
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/*;
|
||||
}
|
||||
|
@ -4,14 +4,32 @@ from tfw.components.source_code_event_handler import SourceCodeEventHandler
|
||||
from tfw.components.terminado_event_handler import TerminadoEventHandler
|
||||
from tfw.components.process_managing_event_handler import ProcessManagingEventHandler
|
||||
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
|
||||
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__':
|
||||
ide = SourceCodeEventHandler(key='webide', directory=tfwenv.WEBIDE_WD, exclude=['__pycache__'])
|
||||
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)
|
||||
|
||||
eventhandlers = {ide, terminado, processmanager}
|
||||
|
Loading…
Reference in New Issue
Block a user