Source

BlingNode / django_ve_init.py

import subprocess
from subprocess import Popen, PIPE
from optparse import OptionParser, make_option

try:
	import common
	common = __import__('common')
except:	
	import initial_preperation
	initial_preperation.install_requirements()
	import common
	common = __import__('common')

def check_program(program_name):
     if common.does_program_exist("/usr/bin/"+program_name) or common.does_program_exist("/usr/local/bin/"+program_name):
        print "---- "+program_name+" is Installed ----"

     else:
          print "---- !"+program_name+" IS MISSING -- ABORTING NOW!----"
          print "---- !PLEASE RUN THE ve_preperation.py SCRIPT NOW!----"
          common.error_exit()

def check_templates():
    template_dir = '/var/lib/misc/blingnode/lib/virtual-env-templates/'
    handler_temp_file ='/var/lib/misc/blingnode/lib/virtual-env-templates/myvirtualdjango.py'
    apache_temp_file ='/var/lib/misc/blingnode/lib/virtual-env-templates/apache_template'

    if common.does_directory_exist(template_dir):
        print "---- The Template Folder is Available ----"

        if common.does_file_exist(handler_temp_file):
            print"---- Handler File is Available ----"
        else:
            print "---- !HANDLER FILE IS MISSING -- ABORTING NOW!----"
            print "---- !PLEASE RUN THE ve_preperation.sh SCRIPT NOW!----"
            common.error_exit()

        if common.does_file_exist(apache_temp_file):
            print "---- Apache File is Available ----"

        else:
            print "---- !APACHE FILE IS MISSING -- ABORTING NOW!----"
            print "---- !PLEASE RUN THE ve_preperation.sh SCRIPT NOW!----"
            common.error_exit()

    else:
        print "---- !TEMPLATE FOLDER IS MISSING -- ABORTING NOW!----"
        print "---- !PLEASE RUN THE ve_preperation.sh SCRIPT NOW!----"
        common.error_exit()

def check_virtualenv(project_name, default_python = None,python_choice = None):
    if not default_python:
        input_message = """\n---- Use the Default Python Version? (y/n):  """
        default_python = common.ask_yes_or_no(query=input_message)

    python_version = 0

    if default_python == "n":
        print "   -!!- WARNING -!!-\n"
        print "-!!- Unless you know how to modify the Python version used by mod_python/Apache2, USE THE DEFAULT VERSION OF PYTHON -!!-"
        print "-!!- You may need to install additional Python Packages for a custom VirtualEnv Version to work! (i.e python-dev2.5 ) -!!-"
        print "-!!- Don't do this unless you know how to modify the Python version used by mod_python/Apache2 -!!-"
        print "-!!- You may need to install additional Python Packages for a custom VirtualEnv Version to work! (i.e python-dev2.5 ) -!!-"
        print "-!!- type 'default (case-sensitive) to use the default python version -!!-'"
        
        if not python_choice:
            python_choice = raw_input( "---- What Version of Python Would You Like? (i.e. 2.5): ")

        #### Check if user changes his mind and wants
        #### to use the default python version
        if python_choice == "default":
            default_python = "y"
        else:
            python_version = python_choice

        print "---- Using Python Version: %s ----" % python_version
    else:
        print "---- Using Default Python Version for New VirtualEnv ----"

    print  "---- CREATING VIRTUAL ENV ----"

    base_folder = "/var/www/%s" % project_name
    env_folder = "%s/env" % base_folder # environment folder

    def to_do():
        print "-- Making New Project Folder --"
        common.command_line_call("sudo mkdir -p %s" % base_folder)

        print "-- CD into Project Folder --"
        common.navigate_to_dir(base_folder)

        if default_python == "y":
            print "---- Creating Virtual Env Using Default Python Version ----"
            common.command_line_call("virtualenv --no-site-packages env")
        elif default_python == "n":
            print "-- Creating Virtual Env Using Python Version: %s --" % python_version
            common.command_line_call("virtualenv --no-site-packages --python=/usr/bin/python%s env" % python_version)
        else:
            print "---- oops try again ----"
            common.error_exit(msg="Invalid choice (not y/n)")

        print "---- Virtual Env Created ----"

    if common.does_directory_exist(base_folder):
        common.on_conflict("virtualenv already exists for %s" % project_name, to_do, base_folder)
    else:
        to_do()

def check_django(project_name):
    base_folder = "/var/www/%s" % project_name
    env_folder = "%s/env" % base_folder # environment folder

    print "---- INSTALLING DJANGO INSIDE THE NEW VIRTUAL ENV ----"

    print "-- Installing Django using Pip Install -E --"
    common.command_line_call("sudo pip install -E %s/ Django" % env_folder)

    print "-- Creating Requirements File with Pip Freeze -E --"
    pip_requirements = common.command_line_call_and_return("pip freeze -E %s/" % env_folder)
    requirements_file = open("%s/requirements.txt" % env_folder, 'w')
    requirements_file.write(pip_requirements)
    requirements_file.close()

    print "-- Installing Packages based on Requirements File --"
    common.command_line_call("sudo pip install -E %s -r %s/requirements.txt" % (env_folder, env_folder))

    print "---- Django Installed ----"

def check_www_apache_template(project_name, domain_name):
    print "---- CREATING APACHE SITES-AVAILABLE FILE ----"

    apache_folder = "/etc/apache2/sites-available"
    apache_file = "%s.%s" % (project_name, domain_name)
    sites_available_file = "%s/%s" % (apache_folder, apache_file)
    
    if APACHE_MOD == 'mod_python':
        apache_template = 'apache_template'
    else:
        apache_template = 'apache_wsgi_template'

    def to_do():
        print "-- Copying Apache Template File and Search n Replacing values --"
        common.copy_and_sub("/var/lib/misc/blingnode/lib/virtual-env-templates/%s" % apache_template, sites_available_file + "_", r'PROJECT_NAME', project_name)
        common.copy_and_sub(sites_available_file + "_", sites_available_file, r'DOMAIN', domain_name)
        common.command_line_call("sudo rm -r %s_" % sites_available_file)

        print "-- Enabling %s --" % apache_file
        common.command_line_call("a2ensite %s" % apache_file)

        print "-- Restarting Apache --"
        common.command_line_call("/etc/init.d/apache2 reload")

        print "---- Apache Site Setup ----"

    if common.does_file_exist(sites_available_file):
        common.on_conflict("sites-available file already exists for %s" % apache_file, to_do, sites_available_file)
    else:
        to_do()

def check_env_folder_permissions(project_name):
    print "---- CREATING PROJECT FOLDER AND SETTING PERMISSIONS ----"
    project_folder = "/var/www/%s/env/www" % project_name
    
    def to_do():
        print "-- Creating Project Folder --"
        common.command_line_call("mkdir %s" % project_folder)
        print "-- Setting Permission to 755 --"
        common.command_line_call("chmod -R 755 /var/www/%s" % project_name)
    
    if common.does_directory_exist(project_folder):
        common.on_conflict("Project folder already exists in %s" % project_folder, to_do, project_folder)
    else:
        to_do()
    
    print "---- Folder Created and Permissions Set ----"

def check_django_project(project_name):
    base_folder = "/var/www/%s" % project_name
    env_folder = "%s/env" % base_folder # environment folder
    project_dir = "%s/www" % env_folder

    print "---- Creating new django project  ----"
    import sys, os
    from copy import copy
    old_sys_path = copy(sys.path)
    print "-- Sourcing into virtualenv --"
    activate_this = os.path.join(env_folder, 'bin', 'activate_this.py')
    execfile(activate_this, dict(__file__=activate_this))
    print "-- CD to %s --" % project_dir
    common.navigate_to_dir(project_dir)
    print "-- Creating django project at %s --" % os.path.join(project_dir, project_name)
    common.command_line_call("sudo %s startproject %s" % (os.path.join(env_folder, 'bin', 'django-admin.py'), project_name))
    work_dir = os.path.join(project_dir, project_name)
    print "-- Implementing local_settings.py convention --"
    settings = open(os.path.join(work_dir, "settings.py"), 'a')
    settings.write( "\n\ntry:\n"
                    "    from local_settings import *\n"
                    "except ImportError:\n"
                    "    pass\n")
    settings.close()
    common.command_line_call("touch %s" % os.path.join(work_dir, 'local_settings.py'))
    sys.path = old_sys_path
    print "---- Django project created ----"

def check_python_handler(options, project_name):
    global APACHE_MOD

    if hasattr(options,'module') and options.module:
        if options.module == 'mod_wsgi' or options.module == 'mod_python':
            module = options.module
        else:
            module = "mod_wsgi"
    else:
        while True:
            choice = raw_input('\nUse mod_wsgi or mod_python? ([mod_wsgi]/mod_python):').lower()
            if choice == 'mod_wsgi' or choice == 'mod_python': 
                module = choice
                break
            elif choice == '':
                module = "mod_wsgi"
                break
            else:
                print '\nInvalid input, please try again.'

    if module == 'mod_wsgi':
        APACHE_MOD = module
        handler = 'myvirtualdjango.wsgi'
    elif module == 'mod_python':
        APACHE_MOD = module
        handler = 'myvirtualdjango.py'
    else:
        print '\nInvalid argument: %s' % (module)
    
    ################################## Creating Python Handler
    print "---- CREATING PYTHON HANDLER -- %s ----" % handler
    print "-- Copy Handler File and Search and Replace PROJECT_NAME in Handler File --"
    common.copy_and_sub("/var/lib/misc/blingnode/lib/virtual-env-templates/%s" % handler,"/var/www/%s/env/%s" % (project_name, handler), r'PROJECT_NAME', project_name, overwrite=True)
    print "-- Giving %s 755 Permissions --" % handler
    common.command_line_call("chmod 755 /var/www/%s/env/%s" % (project_name, handler))
    print "---- Python Handler Created ----"

def main(options, args):

    ############################# Check For root Access
    if not common.is_user_root():
        common.error_exit(msg="\nERROR: Run this script as root\n")
    
    sudo = None

    if options.password:
        print "password: %s" % options.password
        sudo = common.Sudo(password = options.password)

    ############################# CHECK FOR REQUIRED PROGRAMS!
    print  "---- CHECKING IF SERVER IS SETUP CORRECTLY ----"

    programs = ['easy_install','pip','virtualenv']
    for program in programs:
        check_program(program)
    check_templates()

    ############################# THIS IS THE BEGGINNING!

    print "You are setting up a new VIRTUAL ENV. You will be installing the following:"
    print "- Virtual Env Project Folder"
    print "- Python"
    print "- Django"
    print "- Apache Sites-Available File"

    # Show User Variables to Fill
    if hasattr(options,'project') and options.project:
        project_name = options.project
    else:
        project_name = raw_input('\nWhat is the Project Name:\n')
        
    if hasattr(options,'domain') and options.domain:
        domain_name = options.domain
    else:
        domain_name = raw_input("\nWhat domain name will this project be in?\n")
    
    if hasattr(options,'python_version') and options.python_version:
        if options.python_version == "default":
            check_virtualenv(project_name, default_python="y")
        else:
            check_virtualenv(project_name, default_python="n", python_choice=options.python_version)
    else:
        check_virtualenv(project_name)
        
    check_django(project_name)

    check_env_folder_permissions(project_name)
    check_django_project(project_name)
    check_python_handler(options, project_name)

    check_www_apache_template(project_name, domain_name)

    print "---- YOU'RE DONE! ----"
    print "HERE'S WHAT YOU NEED TO DO NOW:"
    print " - CREATE DNS ENTRIES"
    print " - PROBABLY NEED TO MAKE A TRAC AND SVN IF YOU HAVN'T ALREADY"
    print " - START A DJANGO PROJECT INSIDE YOUR NEW VIRTUAL ENV"

if __name__ == "__main__":
    options = [
        make_option('-p', '--password', dest='password', action='store',
            help="User password to send to sudo. Note that this will"
            "appear in the operating system's process list."),
        make_option('--project', dest='project',
            help="Project name"),
        make_option('--domain', dest='domain',
            help="Domain name that the project will be in"),
        make_option('--python_version',dest='python_version', default='default',
            help="Python version to be used to set up the virtual env"),
        make_option('--module',dest='module',
            help="Apache Module to be used for the apache config and handler file"),
    ]

    parser = OptionParser(option_list=options)
    (options, args) = parser.parse_args()
    main(options, args)