Skip to content

Commit

Permalink
Merge pull request #724 from gkadillak/issue#706-websockets
Browse files Browse the repository at this point in the history
Issue#706 websockets
  • Loading branch information
schakrava committed Jul 14, 2015
2 parents 4cadf14 + 6d3ff21 commit 56a4775
Show file tree
Hide file tree
Showing 18 changed files with 551 additions and 427 deletions.
36 changes: 35 additions & 1 deletion base-buildout.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ extra_options =

[extra-stuff]
recipe = plone.recipe.command
command = mkdir -p ${buildout:directory}/var/{log,run} &&
command = mkdir -p ${buildout:directory}/var/log &&
mkdir -p ${buildout:directory}/src/rockstor/logs &&
usermod -a -G root nginx &&
systemctl disable nginx
Expand Down Expand Up @@ -146,3 +146,37 @@ cmds = ${buildout:directory}/bin/django collectstatic --noinput -i admin -v 0
recipe = collective.recipe.template
input = ${buildout:directory}/conf/docker.service.in
output = ${buildout:directory}/conf/docker.service

[js-libraries]
recipe = hexagonit.recipe.download
strip-top-level-dir = true
destination = ${buildout:directory}/static/js/lib
on-update = true
ignore-existing = true

[init-gunicorn]
recipe = collective.recipe.template
bind = 127.0.0.1
port = 8000
workers = 1
user = rocky
pidfile = /run/gunicorn.pid

[supervisord-conf]
recipe = collective.recipe.template
host = 127.0.0.1
port = 9001
logdir = ${buildout:directory}/var/log
logfile = ${supervisord-conf:logdir}/supervisord.log
input = ${buildout:directory}/conf/supervisord.conf.in
output = ${buildout:directory}/etc/supervisord.conf
pidfile = /run/supervisord.pid

[django-settings-conf]
recipe = collective.recipe.template
tapport = 10000
sinkport = 10001
schedulerport = 10001
reppubport = 10002
reprecvport = 10003
input = ${buildout:directory}/conf/settings.conf.in
31 changes: 3 additions & 28 deletions buildout.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -44,23 +44,11 @@ input = ${buildout:directory}/conf/nginx.conf.in
output = ${buildout:directory}/etc/nginx/nginx.conf

[init-gunicorn]
recipe = collective.recipe.template
bind = 127.0.0.1
port = 8000
workers = 1
user = rocky
logfile = ${buildout:directory}/var/log/gunicorn.log
pidfile = ${buildout:directory}/var/run/gunicorn.pid
input = ${buildout:directory}/conf/gunicorn.in
output = ${buildout:directory}/etc/init.d/gunicorn

[supervisord-conf]
recipe = collective.recipe.template
host = 127.0.0.1
port = 9001
logdir = ${buildout:directory}/var/log
logfile = ${supervisord-conf:logdir}/supervisord.log
pidfile = ${buildout:directory}/var/run/supervisord.pid
gunicorn_cmd = ${buildout:directory}/bin/gunicorn --bind=${init-gunicorn:bind}:${init-gunicorn:port} --pid=${init-gunicorn:pidfile} --workers=${init-gunicorn:workers} --log-file=${init-gunicorn:logfile} --pythonpath=${buildout:directory}/src/rockstor --settings=settings --timeout=120 --graceful-timeout=120 wsgi:application
smart_manager_cmd = ${buildout:directory}/bin/sm
replicad_cmd = ${buildout:directory}/bin/replicad
Expand All @@ -69,11 +57,9 @@ dc_cmd = ${buildout:directory}/bin/data-collector
sm_cmd = ${buildout:directory}/bin/service-monitor
jd_cmd = ${buildout:directory}/bin/job-dispatcher
ztask_cmd = ${buildout:directory}/bin/django ztaskd --noreload -l DEBUG --replayfailed -f ${supervisord-conf:logdir}/ztask.log
input = ${buildout:directory}/conf/supervisord.conf.in
output = ${buildout:directory}/etc/supervisord.conf
dc2_cmd = ${buildout:directory}/bin/dc2

[django-settings-conf]
recipe = collective.recipe.template
rootdir = ${buildout:directory}/src/rockstor
datastore = ${django-settings-conf:rootdir}/storageadmin/datastore
smartdb = ${django-settings-conf:rootdir}/smart_manager/smartdb
Expand All @@ -84,24 +70,13 @@ template_dir2 = ${django-settings-conf:rootdir}/templates/admin
smb_conf = ${buildout:directory}/conf/smb.conf
logfile = ${buildout:directory}/var/log/rockstor.log
taplib = ${django-settings-conf:rootdir}/smart_manager/taplib
tapport = 10000
sinkport = 10001
input = ${buildout:directory}/conf/settings.conf.in
output = ${django-settings-conf:rootdir}/settings.py
schedulerport = 10001
reppubport = 10002
reprecvport = 10003
debug = True
kernel = '4.1.0-1.el7.elrepo.x86_64'

[js-libraries]
recipe = hexagonit.recipe.download
url = http://rockstor.com/downloads/js/lib.tgz
md5sum = a949705f5af85db40c92ea1ef8337479
strip-top-level-dir = true
destination = ${buildout:directory}/static/js/lib
on-update = true
ignore-existing = true
url = http://rockstor.com/downloads/jslibs/testing/lib.tgz
md5sum = ee540ba3904d90f49781d3c994ac8220

[postgres-setup]
recipe = plone.recipe.command
Expand Down
7 changes: 7 additions & 0 deletions conf/nginx.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,12 @@ http {
proxy_read_timeout 120;
proxy_pass http://${init-gunicorn:bind}:${init-gunicorn:port}/;
}
location /socket.io {
proxy_pass http://127.0.0.1:8001/socket.io;
proxy_redirect off;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
}
21 changes: 21 additions & 0 deletions conf/supervisord.conf.in
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,24 @@ stdout_logfile_backups=10 ; # of stdout logfile backups (default 10)
stderr_logfile=${supervisord-conf:logdir}/supervisord_%(program_name)s_stderr.log ; stderr log path, NONE for none; default AUTO
stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
stderr_logfile_backups=10 ; # of stderr logfile backups (default 10)

; dc2 daemon
[program:dc2]
environment=DJANGO_SETTINGS_MODULE=settings
command=${supervisord-conf:dc2_cmd} ; the program (relative uses PATH, can take args)
process_name=%(program_name)s ; process_name expr (default %(program_name)s)
numprocs=1 ; number of processes copies to start (def 1)
priority=200
autostart=false ; start at supervisord start (default: true)
autorestart=unexpected ; whether/when to restart (default: unexpected)
startsecs=2 ; number of secs prog must stay running (def. 1)
startretries=3 ; max # of serial start failures (default 3)
exitcodes=0,2 ; 'expected' exit codes for process (default 0,2)
stopsignal=TERM ; signal used to kill process (default TERM)
stopwaitsecs=5 ; max num secs to wait b4 SIGKILL (default 10)
stdout_logfile=${supervisord-conf:logdir}/supervisord_%(program_name)s_stdout.log ; stdout log path, NONE for none; default AUTO
stdout_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
stdout_logfile_backups=10 ; # of stdout logfile backups (default 10)
stderr_logfile=${supervisord-conf:logdir}/supervisord_%(program_name)s_stderr.log ; stderr log path, NONE for none; default AUTO
stderr_logfile_maxbytes=1MB ; max # logfile bytes b4 rotation (default 50MB)
stderr_logfile_backups=10 ; # of stderr logfile backups (default 10)
30 changes: 2 additions & 28 deletions prod-buildout.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -43,35 +43,20 @@ input = ${buildout:directory}/conf/nginx-prod.conf.in
output = ${buildout:directory}/etc/nginx/nginx.conf

[init-gunicorn]
recipe = collective.recipe.template
bind = 127.0.0.1
port = 8000
workers = 1
user = rocky
logfile = ${buildout:depdir}/var/log/gunicorn.log
pidfile = ${buildout:depdir}/var/run/gunicorn.pid
input = ${buildout:directory}/conf/gunicorn.in
output = ${buildout:directory}/etc/init.d/gunicorn

[supervisord-conf]
recipe = collective.recipe.template
host = 127.0.0.1
port = 9001
logdir = ${buildout:depdir}/var/log
logfile = ${supervisord-conf:logdir}/supervisord.log
pidfile = ${buildout:depdir}/var/run/supervisord.pid
gunicorn_cmd = ${buildout:depdir}/bin/gunicorn --bind=${init-gunicorn:bind}:${init-gunicorn:port} --pid=${init-gunicorn:pidfile} --workers=${init-gunicorn:workers} --log-file=${init-gunicorn:logfile} --pythonpath=${buildout:depdir}/src/rockstor --settings=settings --timeout=120 --graceful-timeout=120 wsgi:application
smart_manager_cmd = ${buildout:depdir}/bin/sm
replicad_cmd = ${buildout:depdir}/bin/replicad
ts_cmd = ${buildout:depdir}/bin/task-scheduler
dc_cmd = ${buildout:depdir}/bin/data-collector
sm_cmd = ${buildout:depdir}/bin/service-monitor
ztask_cmd = ${buildout:depdir}/bin/django ztaskd --noreload -f ${supervisord-conf:logdir}/ztask.log
input = ${buildout:directory}/conf/supervisord-prod.conf.in
output = ${buildout:directory}/etc/supervisord.conf

[django-settings-conf]
recipe = collective.recipe.template
rootdir = ${buildout:depdir}/src/rockstor
datastore = ${django-settings-conf:rootdir}/storageadmin/datastore
smartdb = ${django-settings-conf:rootdir}/smart_manager/smartdb
Expand All @@ -81,13 +66,7 @@ template_dir2 = ${django-settings-conf:rootdir}/templates/admin
smb_conf = ${buildout:depdir}/conf/smb.conf
logfile = ${buildout:depdir}/var/log/rockstor.log
taplib = ${django-settings-conf:rootdir}/smart_manager/taplib
tapport = 10000
sinkport = 10001
input = ${buildout:directory}/conf/settings.conf.in
output = ${buildout:directory}/src/rockstor/settings.py
schedulerport = 10001
reppubport = 10002
reprecvport = 10003
debug = False
kernel = '4.1.0-1.el7.elrepo.x86_64'

Expand All @@ -96,13 +75,8 @@ recipe = zc.recipe.egg:scripts
eggs = zc.sourcerelease

[js-libraries]
recipe = hexagonit.recipe.download
url = http://rockstor.com/downloads/js/lib.tgz
md5sum = a949705f5af85db40c92ea1ef8337479
strip-top-level-dir = true
destination = ${buildout:directory}/static/js/lib
on-update = true
ignore-existing = true
url = http://rockstor.com/downloads/jslibs/production/lib.tgz
md5sum = 491e4fa5fb5358521b05aeeb68a43353

[docker]
recipe = plone.recipe.command
Expand Down
6 changes: 5 additions & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
'qgroup-clean = scripts.qgroup_clean:main',
'rockon-json = scripts.rockon_util:main',
'flash-optimize = scripts.flash_optimize:main',
'dc2 = smart_manager.dc2:main',
],
},

Expand All @@ -67,7 +68,10 @@
'six == 1.7.3',
'django-ztask == 0.1.5',
'mock == 1.0.1',
'coverage'
'coverage',
'gevent-socketio',
'psycogreen',
'psutil',
]

)
137 changes: 137 additions & 0 deletions src/rockstor/smart_manager/dc2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
from gevent import monkey
monkey.patch_all()

import gevent
from socketio.server import SocketIOServer
from socketio import socketio_manage
from socketio.namespace import BaseNamespace
from socketio.mixins import BroadcastMixin

from django.conf import settings
from system.osi import (uptime, kernel_info)

from system.services import service_status
import logging
logger = logging.getLogger(__name__)


class ServicesNamespace(BaseNamespace, BroadcastMixin):

# Called before the recv_connect function
def initialize(self):
logger.debug('Services have been initialized')

def recv_connect(self):
logger.debug("Services has connected")
self.emit('services:connected', {
'key': 'services:connected', 'data': 'connected'
})
self.spawn(self.send_service_statuses)

def recv_disconnect(self):
logger.debug("Services have disconnected")

def send_service_statuses(self):
# Iterate through the collection and assign the values accordingly
services = ('nfs', 'smb', 'ntpd', 'winbind', 'netatalk',
'snmpd', 'docker', 'smartd', 'replication',
'nis', 'ldap', 'sftp', 'data-collector', 'smartd',
'service-monitor', 'docker', 'task-scheduler')
while True:
data = {}
for service in services:
data[service] = {}
output, error, return_code = service_status(service)
if (return_code == 0):
data[service]['running'] = return_code
else:
data[service]['running'] = return_code

self.emit('services:get_services', {
'data': data, 'key': 'services:get_services'
})
gevent.sleep(5)


class SysinfoNamespace(BaseNamespace, BroadcastMixin):
start = False
supported_kernel = settings.SUPPORTED_KERNEL_VERSION

# Called before the connection is established
def initialize(self):
logger.debug("Sysinfo has been initialized")

# This function is run once on every connection
def recv_connect(self):
logger.debug("Sysinfo has connected")
self.emit("sysinfo:sysinfo", {
"key": "sysinfo:connected", "data": "connected"
})
self.start = True
gevent.spawn(self.send_uptime)
gevent.spawn(self.send_kernel_info)

# Run on every disconnect
def recv_disconnect(self):
logger.debug("Sysinfo has disconnected")
self.start = False

def send_uptime(self):
# Seems redundant
while self.start:
self.emit('sysinfo:uptime', {
'data': uptime(), 'key': 'sysinfo:uptime'
})
gevent.sleep(30)

def send_kernel_info(self):
try:
self.emit('sysinfo:kernel_info', {
'data': kernel_info(self.supported_kernel),
'key': 'sysinfo:kernel_info'
})
except Exception as e:
logger.debug('kernel error')
# Emit an event to the front end to capture error report
self.emit('sysinfo:kernel_error', {'error': str(e)})
self.error('unsupported_kernel', str(e))


class Application(object):
def __init__(self):
self.buffer = []

def __call__(self, environ, start_response):
path = environ['PATH_INFO'].strip('/') or 'index.html'

if path.startswith('/static') or path == 'index.html':
try:
data = open(path).read()
except Exception:
return not_found(start_response)

if path.endswith(".js"):
content_type = "text/javascript"
elif path.endswith(".css"):
content_type = "text/css"
elif path.endswith(".swf"):
content_type = "application/x-shockwave-flash"
else:
content_type = "text/html"

start_response('200 OK', [('Content-Type', content_type)])
return [data]
if path.startswith("socket.io"):
socketio_manage(environ, {'/services': ServicesNamespace,
'/sysinfo': SysinfoNamespace})


def not_found(start_response):
start_response('404 Not Found', [])
return ['<h1>Not found</h1>']


def main():
logger.debug('Listening on port http://127.0.0.1:8080 and on port 10843 (flash policy server)')
SocketIOServer(('127.0.0.1', 8001), Application(),
resource="socket.io", policy_server=True).serve_forever()
11 changes: 6 additions & 5 deletions src/rockstor/storageadmin/static/storageadmin/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -1660,11 +1660,6 @@ input[type="radio"].selectedRoot {
border-radius: 7px;
}

/* Rockstor update modal dialog */
#update-modal {
margin-left: -380px;
height: 300px;
}

/* Rockstor shutdown modal dialog */
#shutdown-modal {
Expand Down Expand Up @@ -2546,4 +2541,10 @@ This file is generated by `grunt build`, do not edit it by hand.
padding: 10px 15px;
position:relative;
font-weight:bold;
}

#uptime {
float: right;
padding-left: 20px;
color: white;
}
Loading

0 comments on commit 56a4775

Please sign in to comment.