def handle(self, *args, **options):
     interactive = options.get('interactive')
     
     # Avoid import errors
     from nodes.models import Server
     server = Server.objects.first()
     context = {
         'project_name': get_project_name(),
         'project_root': get_project_root(),
         'site_root': get_site_root(),
         'media_root': settings.MEDIA_ROOT,
         'static_root': settings.STATIC_ROOT,
         'cert_path': ca.cert_path,
         'cert_key_path': ca.priv_key_path,
         'mgmt_addr': str(server.mgmt_net.addr),
         'user': options.get('user'),
         'group': options.get('group') or options.get('user'),
         'processes': int(options.get('processes')),
         'threads': int(options.get('threads'))
     }
     
     apache_conf = (
         'WSGIDaemonProcess %(project_name)s user=%(user)s group=%(group)s processes=%(processes)d \\\n'
         '                  threads=%(threads)d python-path=%(site_root)s \\\n'
         '                  display-name=%%{GROUP}\n'
         'WSGIProcessGroup %(project_name)s\n'
         'WSGIScriptAlias / %(project_root)s/wsgi.py\n'
         'WSGIPassAuthorization On\n\n'
         '<Directory %(project_root)s>\n'
         '    <Files wsgi.py>\n'
         '        Order deny,allow\n'
         '        Allow from all\n'
         '    </Files>\n'
         '</Directory>\n\n'
         'Alias /media/ %(media_root)s/\n'
         'Alias /static/ %(static_root)s/\n'
         '<Directory %(static_root)s>\n'
         '    ExpiresActive On\n'
         '    ExpiresByType image/gif A1209600\n'
         '    ExpiresByType image/jpeg A1209600\n'
         '    ExpiresByType image/png A1209600\n'
         '    ExpiresByType text/css A1209600\n'
         '    ExpiresByType text/javascript A1209600\n'
         '    ExpiresByType application/x-javascript A1209600\n'
         '    <FilesMatch "\.(css|js|gz|png|gif|jpe?g|flv|swf|ico|pdf|txt|html|htm)$">\n'
         '        ContentDigest On\n'
         '        FileETag MTime Size\n'
         '    </FilesMatch>\n'
         '</Directory>\n\n'
         'RedirectMatch ^/$ /admin\n\n'
         '<VirtualHost [%(mgmt_addr)s]:443>\n'
         '    ServerName localhost\n'
         '    SSLEngine on\n'
         '    SSLCertificateFile %(cert_path)s\n'
         '    SSLCertificateKeyFile %(cert_key_path)s\n'
         '    SSLCACertificateFile %(cert_path)s\n'
         '    SSLVerifyClient None\n'
         '</VirtualHost>' % context
     )
     
     context.update({
         'apache_conf': apache_conf,
         'apache_conf_file': '/etc/apache2/conf.d/%(project_name)s.conf' % context
     })
     
     # Apache 2.4 compatibility - feature #684
     run('mkdir -p /etc/apache2/conf.d')
     run('mkdir -p /etc/apache2/conf-available')
     
     compat_conf = (
         '# This enables configuration files in the legacy Apache directory.\n'
         'IncludeOptional conf.d/*.conf\n'
         '\n'
         '# These correct access control to Controller files for Apache 2.4.\n'
         '<Directory %(project_root)s>\n'
         '    <Files wsgi.py>\n'
         '        Require all granted\n'
         '    </Files>\n'
         '</Directory>\n'
         '<Location /media>\n'
         '    Require all granted\n'
         '</Location>\n'
         '<Location /static>\n'
         '    Require all granted\n'
         '</Location>' % context
     )
     
     context.update({
         'compat_conf': compat_conf,
         'compat_conf_file': '/etc/apache2/conf-available/local-%(project_name)s-compat.conf' % context
     })
     
     run("echo '%(compat_conf)s' > %(compat_conf_file)s" % context)
     
     # Store apache2 configuration keeping existing one (if any).
     diff = run("echo '%(apache_conf)s'|diff - %(apache_conf_file)s" % context, err_codes=[0,1,2])
     if diff.return_code == 2:
         # File does not exist
         run("echo '%(apache_conf)s' > %(apache_conf_file)s" % context)
     elif diff.return_code == 1:
         # File is different, save the old one
         if interactive:
             msg = ("\n\nFile %(apache_conf_file)s should be updated, do "
                    "you like to override 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 %(apache_conf_file)s %(apache_conf_file)s.\$save" % context)
         run("echo '%(apache_conf)s' > %(apache_conf_file)s" % context)
         self.stdout.write("\033[1;31mA new version of %(apache_conf_file)s "
             "has been installed.\n The old version has been placed at "
             "%(apache_conf_file)s.$save\033[m" % context)
     
     run('a2enmod wsgi')
     run('a2enmod expires')
     run('a2enmod deflate')
     run('a2enmod ssl')
     # catch 127 error 'command not found' for apache 2.2 installations
     run('a2enconf local-%(project_name)s-compat' % context, err_codes=[0, 127])
     
     # Give read permissions to cert key file
     run('chmod g+r %(cert_key_path)s' % context)
Example #2
0
 def handle(self, *args, **options):
     interactive = options.get('interactive')
     
     # Avoid import errors
     from nodes.models import Server
     server = Server.objects.first()
     context = {
         'project_name': get_project_name(),
         'project_root': get_project_root(),
         'site_root': get_site_root(),
         'media_root': settings.MEDIA_ROOT,
         'static_root': settings.STATIC_ROOT,
         'cert_path': ca.cert_path,
         'cert_key_path': ca.priv_key_path,
         'mgmt_addr': str(server.mgmt_net.addr),
         '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'
         '    rewrite ^/$ /admin;\n'
         '    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 /media  {\n'
         '        alias %(media_root)s;\n'
         '        expires 30d;\n'
         '    }\n'
         '    location /static {\n'
         '        alias %(static_root)s;\n'
         '        expires 30d;\n'
         '    }\n'
         '}\n'
         '\n'
         'server {\n'
         '    listen [%(mgmt_addr)s]:443 default_server ssl;\n'
         '    ssl_certificate %(cert_path)s;\n'
         '    ssl_certificate_key %(cert_key_path)s;\n'
         '    rewrite ^/$ /admin;\n'
         '    client_max_body_size 50m;\n'
         '    location / {\n'
         '        uwsgi_pass unix:///var/run/uwsgi/app/%(project_name)s/socket;\n'
         '        include uwsgi_params;\n'
         '    }\n'
         '    location /media  {\n'
         '        alias %(media_root)s;\n'
         '        expires 30d;\n'
         '    }\n'
         '    location /static {\n'
         '        alias %(static_root)s;\n'
         '        expires 30d;\n'
         '    }\n'
         '}\n') % context
     
     uwsgi_conf = (
         '[uwsgi]\n'
         'plugins      = python\n'
         'chdir        = %(site_root)s\n'
         '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, err_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 override "
                        "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, err_codes=[0,1])
     
     # Give read permissions to cert key file
     run('chmod g+r %(cert_key_path)s' % context)
     
     # 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)
Example #3
0
    def handle(self, *args, **options):
        interactive = options.get('interactive')
        
        # Avoid import errors
        from nodes.models import Server
        server = Server.objects.first()
        context = {
            'project_name': get_project_name(),
            'project_root': get_project_root(),
            'site_root': get_site_root(),
            # TODO end with single /
            'media_root': settings.MEDIA_ROOT,
            'static_root': settings.STATIC_ROOT,
            'cert_path': ca.cert_path,
            'cert_key_path': ca.priv_key_path,
            'mgmt_addr': str(server.mgmt_net.addr),
            'user': options.get('user'),
            'group': options.get('group') or options.get('user'),
            'processes': int(options.get('processes')),
            'threads': int(options.get('threads')) }
        
        apache_conf = (
            'WSGIDaemonProcess %(project_name)s user=%(user)s group=%(group)s processes=%(processes)d \\\n'
            '                  threads=%(threads)d python-path=%(site_root)s \\\n'
            '                  display-name=%%{GROUP}\n'
            'WSGIProcessGroup %(project_name)s\n'
            'WSGIScriptAlias / %(project_root)s/wsgi.py\n'
            'WSGIPassAuthorization On\n\n'
            '<Directory %(project_root)s>\n'
            '    Require all granted\n'
            '    <Files wsgi.py>\n'
            '        Order deny,allow\n'
            '        Allow from all\n'
            '    </Files>\n'
            '</Directory>\n\n'
            'Alias /media/ %(media_root)s/\n'
            'Alias /static/ %(static_root)s/\n'
            '<Directory %(static_root)s>\n'
            '    Require all granted\n'
            '    ExpiresActive On\n'
            '    ExpiresByType image/gif A1209600\n'
            '    ExpiresByType image/jpeg A1209600\n'
            '    ExpiresByType image/png A1209600\n'
            '    ExpiresByType text/css A1209600\n'
            '    ExpiresByType text/javascript A1209600\n'
            '    ExpiresByType application/x-javascript A1209600\n'
            '    <FilesMatch "\.(css|js|gz|png|gif|jpe?g|flv|swf|ico|pdf|txt|html|htm)$">\n'
            '        ContentDigest On\n'
            '        FileETag MTime Size\n'
            '    </FilesMatch>\n'
            '</Directory>\n\n'
            'RedirectMatch ^/$ /admin\n\n'
            '<VirtualHost [%(mgmt_addr)s]:443>\n'
            '    ServerName localhost\n'
            '    SSLEngine on\n'
            '    SSLCertificateFile %(cert_path)s\n'
            '    SSLCertificateKeyFile %(cert_key_path)s\n'
            '    SSLCACertificateFile %(cert_path)s\n'
            '    SSLVerifyClient None\n'
            '</VirtualHost>' % context)
        
        context.update({
            'apache_conf': apache_conf,
            'apache_conf_file': '/etc/apache2/sites-enabled/%(project_name)s.conf' % context})
        
        diff = run("echo '%(apache_conf)s'|diff - %(apache_conf_file)s" % context, err_codes=[0,1,2])
        if diff.return_code == 2:
            # File does not exist
            run("echo '%(apache_conf)s' > %(apache_conf_file)s" % context)
        elif diff.return_code == 1:
            # File is different, save the old one
            if interactive:
                msg = ("\n\nFile %(apache_conf_file)s should be updated, do "
                       "you like to override 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 %(apache_conf_file)s %(apache_conf_file)s.\$save" % context)
            run("echo '%(apache_conf)s' > %(apache_conf_file)s" % context)
            self.stdout.write("\033[1;31mA new version of %(apache_conf_file)s "
                "has been installed.\n The old version has been placed at "
                "%(apache_conf_file)s.$save\033[m" % context)
        
#        include_httpd = run("grep '^\s*Include\s\s*httpd.conf\s*' /etc/apache2/apache2.conf", err_codes=[0,1])
#        if include_httpd.return_code == 1:
#            run("echo 'Include httpd.conf' >> /etc/apache2/apache2.conf")
        
        # run('a2ensite %s' % project_name)
        run('a2enmod wsgi')
        run('a2enmod expires')
        run('a2enmod deflate')
        run('a2enmod ssl')
        
        # Give upload file permissions to apache
#        username = run("stat -c %%U %(project_root)s" % context)
#        run('adduser www-data %s' % username)
#        run('chmod g+w %(media_root)s' % context)
        
        # Give read permissions to cert key file
        run('chmod g+r %(cert_key_path)s' % context)