Responsive x11 size

This commit is contained in:
Doro Wu 2015-05-21 14:09:11 +08:00
parent 5d706b6e1e
commit 8cf04c4ae3
7 changed files with 84 additions and 601 deletions

View file

@ -1,4 +1,4 @@
FROM ubuntu:14.04 FROM ubuntu:14.04.2
MAINTAINER Doro Wu <fcwu.tw@gmail.com> MAINTAINER Doro Wu <fcwu.tw@gmail.com>
ENV DEBIAN_FRONTEND noninteractive ENV DEBIAN_FRONTEND noninteractive
@ -14,16 +14,19 @@ RUN apt-get update \
fonts-wqy-microhei \ fonts-wqy-microhei \
language-pack-zh-hant language-pack-gnome-zh-hant firefox-locale-zh-hant libreoffice-l10n-zh-tw \ language-pack-zh-hant language-pack-gnome-zh-hant firefox-locale-zh-hant libreoffice-l10n-zh-tw \
nginx \ nginx \
python-pip \ python-pip python-dev build-essential \
&& apt-get autoclean \ && apt-get autoclean \
&& apt-get autoremove \ && apt-get autoremove \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
ADD web /web/
RUN pip install -r /web/requirements.txt
ADD noVNC /noVNC/ ADD noVNC /noVNC/
ADD nginx.conf /etc/nginx/sites-enabled/default ADD nginx.conf /etc/nginx/sites-enabled/default
ADD startup.sh / ADD startup.sh /
ADD supervisord.conf /etc/ ADD supervisord.conf /etc/supervisor/conf.d/
EXPOSE 6080 EXPOSE 6080
WORKDIR /root WORKDIR /root
ENTRYPOINT ["/startup.sh"] ENTRYPOINT ["/startup.sh"]

View file

@ -1,22 +1,3 @@
# You may add here your
# server {
# ...
# }
# statements for each of your virtual hosts to this file
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# http://wiki.nginx.org/Pitfalls
# http://wiki.nginx.org/QuickStart
# http://wiki.nginx.org/Configuration
#
# Generally, you will want to move this file somewhere, and start with a clean
# file but keep this around for reference. Or just disable in sites-enabled.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##
server { server {
listen 6080 default_server; listen 6080 default_server;
listen [::]:6080 default_server ipv6only=on; listen [::]:6080 default_server ipv6only=on;
@ -25,7 +6,23 @@ server {
index index.html index.htm; index index.html index.htm;
location / { location / {
try_files $uri $uri/ @proxy; try_files $uri @proxy;
}
location = / {
try_files $uri @proxy2;
}
location = /redirect.html {
try_files $uri @proxy2;
}
location @proxy2 {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $host;
proxy_pass http://127.0.0.1:6079;
max_ranges 0;
} }
location @proxy { location @proxy {
@ -36,93 +33,10 @@ server {
max_ranges 0; max_ranges 0;
} }
location /websockify { location = /websockify {
proxy_pass http://127.0.0.1:6081;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade"; proxy_set_header Connection "upgrade";
proxy_pass http://127.0.0.1:6081;
} }
#location / {
# # First attempt to serve request as file, then
# # as directory, then fall back to displaying a 404.
# try_files $uri $uri/ =404;
# # Uncomment to enable naxsi on this location
# # include /etc/nginx/naxsi.rules
# }
# Only for nginx-naxsi used with nginx-naxsi-ui : process denied requests
#location /RequestDenied {
# proxy_pass http://127.0.0.1:8080;
#}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
#error_page 500 502 503 504 /50x.html;
#location = /50x.html {
# root /usr/share/nginx/html;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# fastcgi_split_path_info ^(.+\.php)(/.+)$;
# # NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
#
# # With php5-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php5-fpm:
# fastcgi_pass unix:/var/run/php5-fpm.sock;
# fastcgi_index index.php;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
} }
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# root html;
# index index.html index.htm;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}
# HTTPS server
#
#server {
# listen 443;
# server_name localhost;
#
# root html;
# index index.html index.htm;
#
# ssl on;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
#
# ssl_session_timeout 5m;
#
# ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2;
# ssl_ciphers "HIGH:!aNULL:!MD5 or HIGH:!aNULL:!MD5:!3DES";
# ssl_prefer_server_ciphers on;
#
# location / {
# try_files $uri $uri/ =404;
# }
#}

View file

@ -45,7 +45,7 @@
<body style="margin: 0px;"> <body style="margin: 0px;">
<div id="noVNC_screen"> <div id="noVNC_screen">
<div id="noVNC_status_bar" class="noVNC_status_bar" style="margin-top: 0px;"> <div id="noVNC_status_bar" class="noVNC_status_bar" style="margin-top: 0px; height: 0px;">
<table border=0 width="100%"><tr> <table border=0 width="100%"><tr>
<td><div id="noVNC_status" style="position: relative; height: auto;"> <td><div id="noVNC_status" style="position: relative; height: auto;">
Loading Loading

View file

@ -9,4 +9,6 @@ PASS=ubuntu
id -u ubuntu &>/dev/null || useradd --create-home --shell /bin/bash --user-group --groups adm,sudo ubuntu id -u ubuntu &>/dev/null || useradd --create-home --shell /bin/bash --user-group --groups adm,sudo ubuntu
echo "ubuntu:$PASS" | chpasswd echo "ubuntu:$PASS" | chpasswd
/usr/bin/supervisord -c /etc/supervisord.conf -n cd /web && ./run.py > /var/log/web.log 2>&1 &
nginx -c /etc/nginx/nginx.conf
/usr/bin/supervisord -n

View file

@ -1,13 +1,3 @@
[supervisord]
nodaemon=true
logfile_maxbytes=10MB
pidfile=/var/run/supervisord.pid
logfile=/var/log/supervisord.log
nodaemon=false
[supervisorctl]
serverurl=unix:///var/run/supervisor.sock
[program:xvfb] [program:xvfb]
priority=10 priority=10
directory=/ directory=/
@ -45,7 +35,7 @@ redirect_stderr=true
[program:novnc] [program:novnc]
priority=25 priority=25
directory=/noVNC directory=/noVNC
command=/noVNC/utils/launch.sh command=/noVNC/utils/launch.sh --listen 6081
user=root user=root
autostart=true autostart=true
autorestart=true autorestart=true

View file

@ -1,9 +1,6 @@
from flask import (Flask, from flask import (Flask,
request, request,
render_template,
abort, abort,
Response,
redirect,
) )
import os import os
@ -24,29 +21,14 @@ LoggingConfiguration.set(
logging.DEBUG if os.getenv('DEBUG') else logging.INFO, logging.DEBUG if os.getenv('DEBUG') else logging.INFO,
'lightop.log', name='Web') 'lightop.log', name='Web')
from auth import auth
auth.init_app(app, app.config['PHASE'])
from gevent import spawn, sleep
from geventwebsocket import WebSocketError
import requests
import websocket
import docker
import json import json
from functools import wraps from functools import wraps
import subprocess import subprocess
import datetime import time
import sha
import re
from db.sql import User as DbUser
CHUNK_SIZE = 1024 FIRST = True
CID2IMAGE = {'ubuntu-trusty-ttyjs': 'dorowu/lightop-ubuntu-trusty-ttyjs',
'ubuntu-trusty-lxde': 'dorowu/lightop-ubuntu-trusty-lxde'}
RE_OWNER_CNAME = re.compile('^/(.*)_({})$'.format('|'.join(CID2IMAGE.keys())))
def exception_to_json(func): def exception_to_json(func):
@ -79,461 +61,63 @@ class BadRequest(Exception):
pass pass
HTML_INDEX = '''<html><head>
<script type="text/javascript">
var w = window,
d = document,
e = d.documentElement,
g = d.getElementsByTagName('body')[0],
x = w.innerWidth || e.clientWidth || g.clientWidth,
y = w.innerHeight|| e.clientHeight|| g.clientHeight;
window.location.href = "redirect.html?width=" + x + "&height=" + (parseInt(y));
</script>
<title>Page Redirection</title>
</head><body></body></html>'''
HTML_REDIRECT = '''<html><head>
<script type="text/javascript">
var port = window.location.port;
if (!port)
port = window.location.protocol[4] == 's' ? 443 : 80;
window.location.href = "vnc_auto.html";
</script>
<title>Page Redirection</title>
</head><body></body></html>'''
@app.route('/') @app.route('/')
def index(): def index():
return redirect("index.html") return HTML_INDEX
@app.route('/<path:url>') @app.route('/redirect.html')
@auth.login_required def redirectme():
def root(url): global FIRST
logging.info("Root route, path: %s", url)
# If referred from a proxy request, then redirect to a URL with the proxy prefix.
# This allows server-relative and protocol-relative URLs to work.
proxy_ref = proxy_ref_info(request)
if proxy_ref:
redirect_url = "/p/%s/%s%s" % (proxy_ref[0], url, ("?" + request.query_string if request.query_string else ""))
logging.info("Redirecting referred URL to: %s", redirect_url)
return redirect(redirect_url)
# Otherwise, default behavior
return render_template('hello.html', name=url, request=request)
if not FIRST:
return HTML_REDIRECT
@app.route('/u/<cid>/') env = {'width': 1024, 'height': 768}
@auth.login_required
def proxy_user_root(cid):
return proxy_user(cid, '')
def container_create_and_network(cid):
user = auth.current_user.username()
cname = user + '_' + cid
dc = docker.Client()
# create container
for c in dc.containers(all=True):
#logging.info(str(c['Names']))
if '/' + cname in c['Names']:
break
else:
if cid not in CID2IMAGE:
raise BadRequest(cid, 'not exist')
try:
os.makedirs('mnt/home/' + user)
except OSError:
pass
try:
os.makedirs('mnt/public')
except OSError:
pass
env = ['USER=' + user, 'PASS=' + user]
if 'width' in request.args: if 'width' in request.args:
env.append('WIDTH=' + str(request.args['width'])) env['width'] = request.args['width']
if 'height' in request.args: if 'height' in request.args:
env.append('HEIGHT=' + str(request.args['height'])) env['height'] = request.args['height']
logging.info('create container')
dc.create_container(CID2IMAGE[cid], name=cname,
volumes=['/home/' + user, '/mnt/public'],
environment=env)
cinfo = dc.inspect_container(user + '_' + cid)
# start container
logging.info(cinfo['State']['Running'])
if not cinfo['State']['Running']:
binds = {}
binds[os.path.join(os.getcwd(), 'mnt', 'home', user)] = {'bind': '/home/' + user, 'ro': False}
binds[os.path.join(os.getcwd(), 'mnt', 'public')] = {'bind': '/mnt/public', 'ro': False}
logging.info('start container')
dc.start(cname, binds=binds)
cinfo = dc.inspect_container(user + '_' + cid)
# get ip and port
ipaddr = cinfo['NetworkSettings']['IPAddress']
for p in cinfo['NetworkSettings']['Ports'].keys():
port, proto = p.split('/')
if port != '22':
port = int(port)
break
else:
raise RuntimeError('port', cinfo['NetworkSettings']['Ports'])
start = datetime.datetime.now() # sed
while True: subprocess.check_call(r"sed -i 's#^command=/usr/bin/Xvfb.*$#command=/usr/bin/Xvfb :1 -screen 0 {width}x{height}x16#' /etc/supervisor/conf.d/supervisord.conf".format(**env),
now = datetime.datetime.now()
if (now - start).total_seconds() > 10:
logging.error('probe failed')
raise RuntimeError('probe failed')
try:
r = requests.get('http://{}:{}/'.format(ipaddr, port))
if 200 <= r.status_code < 400:
break
except Exception:
pass
sleep(1)
return ipaddr, port
# hijact LXDE VNC
@app.route('/u/ubuntu-trusty-lxde/<path:path>')
@auth.login_required
def proxy_user_vnc(path):
logging.info('vnc ' + path)
# auth pass
if path.endswith('/websockify'):
logging.info('vnc done')
return ''
if path != 'vnc_auto.html':
return proxy_user('ubuntu-trusty-lxde', path)
if len(request.args.get('hijact', '')) >= 1:
return proxy_user('ubuntu-trusty-lxde', path)
ipaddr, port = container_create_and_network('ubuntu-trusty-lxde')
user = auth.current_user.username()
#TODO remove when user deleted
subprocess.check_call(r"sed -i '/^location .*ubuntu-trusty-lxde\/{user}\//,/}}/d' nginx/ws-login.conf".format(user=user),
shell=True) shell=True)
with open('nginx/ws-login.conf', 'a+') as f: # supervisorctrl reload
f.write('\nlocation /u/ubuntu-trusty-lxde/{user}/websockify\n' subprocess.check_call(r"supervisorctl reload", shell=True)
'{{\n'
' auth_request /login_refresh_code;\n'
' proxy_pass http://{ipaddr}:{port}/websockify;\n'
' proxy_redirect off;\n'
' proxy_buffering off;\n'
' proxy_set_header Host $host;\n'
' proxy_set_header X-Real-IP $remote_addr;\n'
' proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n'
' proxy_http_version 1.1;\n'
' proxy_set_header Upgrade $http_upgrade;\n'
' proxy_set_header Connection "Upgrade";\n'
'}}'.format(user=user, ipaddr=ipaddr, port=port)
)
subprocess.check_call('sudo nginx -c ' + os.getcwd() +
'/nginx.conf -s reload', shell=True)
geometry = '' # check all running
geometry += '&width=' + request.args.get('width', '1024') for i in xrange(20):
geometry += '&height=' + request.args.get('height', '768') output = subprocess.check_output(r"supervisorctl status | grep RUNNING | wc -l", shell=True)
return redirect('/u/ubuntu-trusty-lxde/' + if output.strip() == "4":
'vnc.html' + FIRST = False
('?host={host}&port={port}&path={path}' return HTML_REDIRECT
'&hijact=1&autoconnect=1{geometry}').format( time.sleep(2)
host=re.findall('https?://([^/:]+)([:0-9]*)/', request.url_root)[0][0], abort(500, 'service is not ready, please restart container')
port=6051,
path='u/ubuntu-trusty-lxde/' + user + '/websockify',
geometry=geometry)
)
@app.route('/u/<cid>/<path:path>')
@auth.login_required
def proxy_user(cid, path):
try:
ipaddr, port = container_create_and_network(cid)
except docker.errors.APIError as e:
return json.dumps({'status': 400, 'message': str(e)})
except RuntimeError as e:
return json.dumps({'status': 500, 'message': str(e)})
# websocket
if request.environ.get('wsgi.websocket'):
return proxy_user_websocket(ipaddr, port, path)
# page
url = '%s:%d' % (ipaddr, port)
if len(path) > 0:
url += '/' + path
r = get_source_rsp(url)
logging.info("Got %s response from %s", r.status_code, url)
headers = dict(r.headers)
def generate():
for chunk in r.iter_content(CHUNK_SIZE):
yield chunk
return Response(generate(), headers=headers)
@app.route("/session", methods=["GET"])
@exception_to_json
def sessions():
return json.dumps(CID2IMAGE.keys())
@app.route("/user/", methods=["GET"])
@exception_to_json
@auth.login_required
def users():
user = auth.current_user.username()
if user != 'admin':
raise PermissionDenied('admin only')
result = []
for u in DbUser.select():
result.append({'name': u.user,
'id': u.id,
'volume': ['/mnt/public', '/home/' + u.user]})
return json.dumps(result)
@app.route("/user/", methods=["POST"])
@exception_to_json
@auth.login_required
def user_create():
user = auth.current_user.username()
if user != 'admin':
raise PermissionDenied('admin only')
try:
username = request.form['username']
password = request.form['password']
except KeyError:
raise BadRequest('username or password')
u = DbUser.create(user=username, password=sha.new(password).hexdigest())
return user_detail(u.id)
@app.route("/user/<int:uid>", methods=["GET"])
@exception_to_json
@auth.login_required
def user_detail(uid):
user = auth.current_user.username()
if user != 'admin':
raise PermissionDenied('admin only')
try:
u = DbUser.get(DbUser.id == uid)
except:
return '{}'
return json.dumps({'name': u.user,
'id': u.id,
'volume': ['/mnt/public', '/home/' + u.user]})
@app.route("/user/<int:uid>", methods=["DELETE"])
@exception_to_json
@auth.login_required
def user_delete(uid):
user = auth.current_user.username()
if user != 'admin':
raise PermissionDenied('admin only')
try:
u = DbUser.get(DbUser.id == uid)
except:
return json.dumps({'num': 0})
return json.dumps({'num': u.delete_instance()})
@app.route("/login", methods=["POST", "PUT"])
@exception_to_json
def login():
"""Login
"""
try:
kargs = dict()
kargs['username'] = request.form['username']
kargs['password'] = request.form['password']
kargs['remember'] = request.form['remember'] \
if 'remember' in request.form else False
except KeyError:
raise BadRequest('username, password or sid')
user = auth.login(**kargs)
if user is not None:
if user.is_anonymous():
return json.dumps({'username': 'nobody',
'isAdmin': False,
'anonymous': True})
return json.dumps({'username': user.username(),
'isAdmin': user.is_admin()})
raise PermissionDenied('Wrong user name or password')
@app.route("/container/", methods=["GET"])
@exception_to_json
@auth.login_required
def containers():
user = auth.current_user.username()
if user != 'admin':
raise PermissionDenied('admin only')
result = []
dc = docker.Client()
for c in dc.containers():
r = RE_OWNER_CNAME.match(c['Names'][0])
if r is None:
continue
result.append({'id': c['Id'],
'session': r.group(2),
'owner': r.group(1)})
return json.dumps(result)
@app.route("/container/<string:cid>", methods=["DELETE"])
@exception_to_json
@auth.login_required
def container_delete(cid):
user = auth.current_user.username()
if user != 'admin':
raise PermissionDenied('admin only')
try:
dc = docker.Client()
logging.info(cid)
c = dc.inspect_container(cid)
r = RE_OWNER_CNAME.match(c['Name'])
if r is None:
raise RuntimeError()
dc.kill(cid)
dc.remove_container(cid)
except Exception as e:
logging.error(str(e))
return json.dumps({'num': 0})
return json.dumps({'num': 1})
@app.route("/login_refresh", methods=["GET"])
@exception_to_json
@auth.login_required
def login_refresh():
"""Refresh token
"""
user = auth.current_user
#raise PermissionDenied('Not a valid user')
return json.dumps({'username': user.username(), 'isAdmin': False})
@app.route("/login_refresh_code", methods=["GET"])
@exception_to_json
@auth.login_required
def login_refresh_code():
"""Refresh token
"""
logging.info('!!!!!!!!!!!!!!!!! refresh code')
user = auth.current_user
#raise PermissionDenied('Not a valid user')
return json.dumps({'username': user.username(), 'isAdmin': False})
@app.route("/logout", methods=["PUT"])
@exception_to_json
@auth.login_required
def logout():
"""Logout
"""
try:
username = auth.current_user.username()
except KeyError:
return json.dumps({'error': {'code': 400}})
if auth.logout(username):
return json.dumps({'username': username})
return json.dumps({'error': {'code': 403}})
def proxy_user_websocket(ipaddr, port, path):
def c2s(client, server):
while True:
inp = client.receive()
if inp is None:
raise WebSocketError()
server.send(inp)
def get_headers():
headers = []
#for header in request.environ:
# if not header.startswith('HTTP_'):
# continue
# if not header.startswith('HTTP_SEC_') \
# and not header.startswith('HTTP_ACCEPT_') \
# and not header.startswith('HTTP_USER_AGENT'):
# continue
# upper = True
# k = ''
# for c in header[5:].replace('_', '-').lower():
# if upper:
# k += c.upper()
# upper = False
# else:
# k += c
# if c == '-':
# upper = True
# headers.append('%s: %s' % (k, request.environ[header]))
return headers
#https://stackoverflow.com/questions/18240358/html5-websocket-connecting-to-python
client = request.environ['wsgi.websocket']
url = '%s:%d' % (ipaddr, port)
if len(path) > 0:
url += '/' + path
logging.info('websocket: ' + url)
headers = []
#headers = get_headers()
#logging.info('headers: ' + str(headers))
server = websocket.create_connection("ws://" + url, header=headers)
try:
spawn(c2s, client, server)
while True:
inp = server.recv()
if inp is None:
raise WebSocketError()
client.send(inp)
except WebSocketError as e:
logging.error(e)
except client.WebSocketConnectionClosedException:
pass
return json.dumps({'status': 200})
def get_source_rsp(url):
url = 'http://%s' % url
logging.info("Fetching %s", url)
# Ensure the URL is approved, else abort
if not is_approved(url):
logging.warn("URL is not approved: %s", url)
abort(403)
# Pass original Referer for subsequent resource requests
proxy_ref = proxy_ref_info(request)
headers = {"Referer": "http://%s/%s" % (proxy_ref[0], proxy_ref[1])} if proxy_ref else {}
# Fetch the URL, and stream it back
logging.info("Fetching with headers: %s, %s", url, headers)
return requests.get(url, stream=True, params=request.args, headers=headers)
def is_approved(url):
return True
def split_url(url):
"""Splits the given URL into a tuple of (protocol, host, uri)"""
proto, rest = url.split(':', 1)
rest = rest[2:].split('/', 1)
host, uri = (rest[0], rest[1]) if len(rest) == 2 else (rest[0], "")
return (proto, host, uri)
def proxy_ref_info(request):
"""Parses out Referer info indicating the request is from a previously proxied page.
For example, if:
Referer: http://localhost:8080/p/google.com/search?q=foo
then the result is:
("google.com", "search?q=foo")
"""
ref = request.headers.get('referer')
if ref:
_, _, uri = split_url(ref)
if uri.find("/") < 0:
return None
first, rest = uri.split("/", 1)
if first in "pd":
parts = rest.split("/", 1)
r = (parts[0], parts[1]) if len(parts) == 2 else (parts[0], "")
logging.info("Referred by proxy host, uri: %s, %s", r[0], r[1])
return r
return None
for image in CID2IMAGE.values():
image = image.split(':')[0]
cmd = 'docker images | grep -q "^{0} " || docker pull {0}'.format(image)
logging.info(cmd)
subprocess.check_call(cmd, shell=True)
try:
os.makedirs('nginx')
except:
pass
with open('nginx/ws-login.conf', 'w+') as f:
f.truncate()
if __name__ == '__main__': if __name__ == '__main__':

View file

@ -92,20 +92,11 @@ def main():
create_instance_config() create_instance_config()
def run_server(): def run_server():
from gevent import monkey
monkey.patch_all(subprocess=True)
from gevent.wsgi import WSGIServer
import socket import socket
from geventwebsocket.handler import WebSocketHandler
os.environ['CONFIG'] = CONFIG os.environ['CONFIG'] = CONFIG
from lightop import app from lightop import app
if not DEBUG: # run on NAS
from werkzeug import SharedDataMiddleware
app.wsgi_app = SharedDataMiddleware(app.wsgi_app, {
'/': os.path.join(os.path.dirname(__file__), 'static')
})
# websocket conflict: WebSocketHandler # websocket conflict: WebSocketHandler
if DEBUG or STAGING: if DEBUG or STAGING:
# from werkzeug.debug import DebuggedApplication # from werkzeug.debug import DebuggedApplication
@ -123,9 +114,7 @@ def main():
print('Running on port ' + str(PORT)) print('Running on port ' + str(PORT))
try: try:
http_server = WSGIServer(('', PORT), app, app.run(host='', port=PORT)
handler_class=WebSocketHandler)
http_server.serve_forever()
except socket.error as e: except socket.error as e:
print(e) print(e)
@ -133,8 +122,9 @@ def main():
STAGING = True if '--staging' in sys.argv else False STAGING = True if '--staging' in sys.argv else False
CONFIG = 'config.Development' if DEBUG else 'config.Production' CONFIG = 'config.Development' if DEBUG else 'config.Production'
CONFIG = 'config.Staging' if STAGING else CONFIG CONFIG = 'config.Staging' if STAGING else CONFIG
PORT = 6050 PORT = 6079
PROGRAMS = (('sudo nginx -c ${PWD}/nginx.conf'),) PROGRAMS = tuple()
#PROGRAMS = (('sudo nginx -c ${PWD}/nginx.conf'),)
#PROGRAMS = ('python lxc-monitor.py', #PROGRAMS = ('python lxc-monitor.py',
# 'python docker-monitor.py') # 'python docker-monitor.py')
signal.signal(signal.SIGCHLD, signal.SIG_IGN) signal.signal(signal.SIGCHLD, signal.SIG_IGN)