2014-05-08 16:59:35 +00:00
|
|
|
from optparse import make_option
|
|
|
|
from os.path import expanduser
|
|
|
|
|
|
|
|
from django.conf import settings
|
|
|
|
from django.core.management.base import BaseCommand
|
|
|
|
|
2015-03-31 12:39:08 +00:00
|
|
|
from orchestra.utils.paths import get_project_dir, get_site_dir, get_project_name
|
2015-04-05 10:46:24 +00:00
|
|
|
from orchestra.utils.sys import run, check_root, get_default_celeryd_username
|
2014-05-08 16:59:35 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Command(BaseCommand):
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
super(Command, self).__init__(*args, **kwargs)
|
|
|
|
self.option_list = BaseCommand.option_list + (
|
|
|
|
make_option('--user', dest='user', default=get_default_celeryd_username(),
|
|
|
|
help='uWSGI daemon user.'),
|
|
|
|
make_option('--group', dest='group', default='',
|
|
|
|
help='uWSGI daemon group.'),
|
|
|
|
make_option('--processes', dest='processes', default=4,
|
|
|
|
help='uWSGI number of processes.'),
|
|
|
|
make_option('--noinput', action='store_false', dest='interactive', default=True,
|
|
|
|
help='Tells Django to NOT prompt the user for input of any kind. '
|
|
|
|
'You must use --username with --noinput, and must contain the '
|
|
|
|
'cleeryd process owner, which is the user how will perform tincd updates'),
|
|
|
|
)
|
|
|
|
|
|
|
|
option_list = BaseCommand.option_list
|
|
|
|
help = 'Configures nginx + uwsgi to run with your Orchestra instance.'
|
|
|
|
|
|
|
|
@check_root
|
|
|
|
def handle(self, *args, **options):
|
|
|
|
interactive = options.get('interactive')
|
|
|
|
|
|
|
|
context = {
|
|
|
|
'project_name': get_project_name(),
|
2015-03-31 12:39:08 +00:00
|
|
|
'project_dir': get_project_dir(),
|
|
|
|
'site_dir': get_site_dir(),
|
2014-05-08 16:59:35 +00:00
|
|
|
'static_root': settings.STATIC_ROOT,
|
|
|
|
'user': options.get('user'),
|
|
|
|
'group': options.get('group') or options.get('user'),
|
|
|
|
'home': expanduser("~%s" % options.get('user')),
|
|
|
|
'processes': int(options.get('processes')),}
|
|
|
|
|
|
|
|
nginx_conf = (
|
|
|
|
'server {\n'
|
|
|
|
' listen 80;\n'
|
|
|
|
' listen [::]:80 ipv6only=on;\n'
|
2015-03-01 11:56:54 +00:00
|
|
|
' rewrite ^/$ /admin/;\n'
|
2014-05-08 16:59:35 +00:00
|
|
|
' client_max_body_size 500m;\n'
|
|
|
|
' location / {\n'
|
|
|
|
' uwsgi_pass unix:///var/run/uwsgi/app/%(project_name)s/socket;\n'
|
|
|
|
' include uwsgi_params;\n'
|
|
|
|
' }\n'
|
|
|
|
' location /static {\n'
|
|
|
|
' alias %(static_root)s;\n'
|
|
|
|
' expires 30d;\n'
|
|
|
|
' }\n'
|
|
|
|
'}\n') % context
|
|
|
|
|
|
|
|
uwsgi_conf = (
|
|
|
|
'[uwsgi]\n'
|
|
|
|
'plugins = python\n'
|
2015-03-31 12:39:08 +00:00
|
|
|
'chdir = %(site_dir)s\n'
|
2014-05-08 16:59:35 +00:00
|
|
|
'module = %(project_name)s.wsgi\n'
|
|
|
|
'master = true\n'
|
|
|
|
'processes = %(processes)d\n'
|
|
|
|
'chmod-socket = 664\n'
|
|
|
|
'stats = /run/uwsgi/%%(deb-confnamespace)/%%(deb-confname)/statsocket\n'
|
|
|
|
'vacuum = true\n'
|
|
|
|
'uid = %(user)s\n'
|
|
|
|
'gid = %(group)s\n'
|
|
|
|
'env = HOME=%(home)s\n') % context
|
|
|
|
|
|
|
|
nginx = {
|
|
|
|
'file': '/etc/nginx/conf.d/%(project_name)s.conf' % context,
|
|
|
|
'conf': nginx_conf }
|
|
|
|
uwsgi = {
|
|
|
|
'file': '/etc/uwsgi/apps-available/%(project_name)s.ini' % context,
|
|
|
|
'conf': uwsgi_conf }
|
|
|
|
|
|
|
|
for extra_context in (nginx, uwsgi):
|
|
|
|
context.update(extra_context)
|
|
|
|
diff = run("echo '%(conf)s'|diff - %(file)s" % context, error_codes=[0,1,2])
|
|
|
|
if diff.return_code == 2:
|
|
|
|
# File does not exist
|
|
|
|
run("echo '%(conf)s' > %(file)s" % context)
|
|
|
|
elif diff.return_code == 1:
|
|
|
|
# File is different, save the old one
|
|
|
|
if interactive:
|
|
|
|
msg = ("\n\nFile %(file)s be updated, do you like to overide "
|
|
|
|
"it? (yes/no): " % context)
|
|
|
|
confirm = input(msg)
|
|
|
|
while 1:
|
|
|
|
if confirm not in ('yes', 'no'):
|
|
|
|
confirm = input('Please enter either "yes" or "no": ')
|
|
|
|
continue
|
|
|
|
if confirm == 'no':
|
|
|
|
return
|
|
|
|
break
|
|
|
|
run("cp %(file)s %(file)s.save" % context)
|
|
|
|
run("echo '%(conf)s' > %(file)s" % context)
|
|
|
|
self.stdout.write("\033[1;31mA new version of %(file)s has been installed.\n "
|
|
|
|
"The old version has been placed at %(file)s.save\033[m" % context)
|
|
|
|
|
|
|
|
run('ln -s /etc/uwsgi/apps-available/%(project_name)s.ini /etc/uwsgi/apps-enabled/' % context, error_codes=[0,1])
|
|
|
|
|
|
|
|
# nginx should start after tincd
|
|
|
|
current = "\$local_fs \$remote_fs \$network \$syslog"
|
|
|
|
run('sed -i "s/ %s$/ %s \$named/g" /etc/init.d/nginx' % (current, current))
|
|
|
|
|
|
|
|
rotate = (
|
|
|
|
'/var/log/nginx/*.log {\n'
|
|
|
|
' daily\n'
|
|
|
|
' missingok\n'
|
|
|
|
' rotate 30\n'
|
|
|
|
' compress\n'
|
|
|
|
' delaycompress\n'
|
|
|
|
' notifempty\n'
|
|
|
|
' create 640 root adm\n'
|
|
|
|
' sharedscripts\n'
|
|
|
|
' postrotate\n'
|
|
|
|
' [ ! -f /var/run/nginx.pid ] || kill -USR1 `cat /var/run/nginx.pid`\n'
|
|
|
|
' endscript\n'
|
|
|
|
'}\n')
|
|
|
|
run("echo '%s' > /etc/logrotate.d/nginx" % rotate)
|
|
|
|
|
|
|
|
# Allow nginx to write to uwsgi socket
|
|
|
|
run('adduser www-data %(group)s' % context)
|