Source code for modules.django

"""
Django deployment module.
Creates necessary folders for housing project source code
clones, deploys, submodule checkouts

.. _django-module-settings:

Django Module Settings
----------------------
::

    DJANGO_GIT_REPO_URL = "git://your/repo.git" #django project repo url
    DJANGO_STAGING_GIT_BRANCH = "develop"
    DJANGO_STAGING_SERVER_NAME = "staging.some_project.com"
    DJANGO_PRODUCTION_GIT_BRANCH = "master"
    DJANGO_PRODUCTION_SERVER_NAME = "production.some_project.com"
    DJANGO_GUNICORN_PORT = '9010'
    DJANGO_LOCALSETTINGS_LOCAL_PATH = "localsettings.py" #Path to localsettings on local machine
    
#    A dictionary you can use if you want to treat localsettings as a template.
#    This dict get's autopopulated with other useful keys:
#    * project_root
#    * www_root - holds the log_dir and code_root
#    * log_dir
#    * code_root - where your django code ends up
#    * project_media - django media folder (in your code_root by default) ((usually used by collectstatic))
#    * project_static - django static files folder location, also in code_root by default
#    * virtualenv_root
#    * services - path where things like apache.conf and supervisor.conf end up.
    DJANGO_LOCALSETTINGS_TEMPLATE_DICT = {}
    DJANGO_LOCALSETTINGS_REMOTE_DESTINATION = "some_folder/localsettings.py" #RELATIVE TO THE CODE_ROOT ON REMOTE MACHINE
    DJANGO_LOCALSETTINGS_NO_TEMPLATE = True #Set to false if you want to treat localsettings.py as a template

"""

from fabric.api import *
from fabric.colors import green, yellow
from fabric.contrib import files, console
from fabric import utils
import posixpath
from fabric.contrib.files import upload_template
import settings

def setup_env(deploy_level="staging"):
    if deploy_level == "staging":
        _staging()
    elif deploy_level == "production":
        _production()
    else:
        raise Exception("Unrecognized Deploy Level: %s" % deploy_level)

    env.user = settings.SUDO_USER
    env.sudo_user = settings.SUDO_USER
    env.code_repo = settings.DJANGO_GIT_REPO_URL
    env.project = settings.PROJECT_NAME
    env.server_port = settings.DJANGO_GUNICORN_PORT
    env.settings = '%(project)s.localsettings' % env
    env.db = '%s_%s' % (env.project, env.environment)
    _setup_path()
    print '\t'
    print '\t'
    print yellow('########WARNING###########')
    print yellow('## REQUIRE USER: "%(sudo_user)s" login password! ##' % env)
    print '\t'
    print '\t'
def _setup_path():
    """
    Creates all the various paths that will be needed
    in deploying code, populating config templates, etc.
    """
    # using posixpath to ensure unix style slashes. See bug-ticket: http://code.fabfile.org/attachments/61/posixpath.patch
    env.project_root = settings.PROJECT_ROOT
    env.www_root = posixpath.join(env.project_root,'www',env.environment)
    env.log_dir = posixpath.join(env.www_root,'log')
    env.code_root = posixpath.join(env.www_root,'code_root')
    env.project_media = posixpath.join(env.code_root, 'media')
    env.project_static = posixpath.join(env.project_root, 'static')
    env.virtualenv_name = getattr(settings, 'PYTHON_ENV_NAME', 'python_env') #not a required setting and should be sufficient with default name
    env.virtualenv_root = posixpath.join(env.www_root, env.virtualenv_name)
    env.services = posixpath.join(env.project_root, 'services')

[docs]def setup_dirs(): """ create (if necessary) and make writable uploaded media, log, etc. directories """ require('project_root',provided_by=('setup_env')) sudo('mkdir -p %(project_root)s' % env, user=env.sudo_user) sudo('mkdir -p %(www_root)s' % env, user=env.sudo_user) sudo('mkdir -p %(log_dir)s' % env, user=env.sudo_user) sudo('mkdir -p %(virtualenv_root)s' % env, user=env.sudo_user) sudo('mkdir -p %(services)s' % env, user=env.sudo_user) sudo('chmod -R a+w %(log_dir)s' % env, user=env.sudo_user) sudo('chown -R %(sudo_user)s %(project_root)s' % env) sudo('chgrp -R %(sudo_user)s %(project_root)s' % env)
def _production(): """ use production environment on remote host""" env.code_branch = settings.DJANGO_PRODUCTION_GIT_BRANCH env.environment = 'production' env.server_name = 'project-production.dimagi.com' env.hosts = [settings.PRODUCTION_HOST] def _staging(): """ use staging environment on remote host""" env.code_branch = settings.DJANGO_STAGING_GIT_BRANCH env.environment = 'staging' env.server_name = 'project-staging.dimagi.com' env.hosts = [settings.STAGING_HOST]
[docs]def collectstatic(): """ run collectstatic on remote environment. ASSUMES YOU ALREADY HAVE ALL REQUIRED PACKAGES AND VIRTUALENV INSTALLED. """ require('project_root', provided_by=('setup_env')) with cd(env.project_root): sudo('%(virtualenv_root)s/bin/python manage.py collectstatic --noinput --settings=%(settings)s' % env, user=env.sudo_user)
[docs]def clone_repo(): """ clone a new copy of the git repository """ require('code_root', provided_by=('setup_env')) with cd(env.www_root): sudo('git clone %(code_repo)s %(code_root)s' % env, user=env.sudo_user)
def _make_template_dict(): """ Adds the localsettings template dict to env and populates it with some additional useful things """ d = settings.DJANGO_LOCALSETTINGS_TEMPLATE_DICT d["project_root"] = env.project_root d["www_root"] = env.www_root d["log_dir"] = env.log_dir d["code_root"] = env.code_root d["project_media"] = env.project_media d["project_static"] = env.project_static d["virtualenv_root"] = env.virtualenv_root d["services"] = env.services env.localsettings_dict = d
[docs]def upload_localsettings(): """ Uploads your django settings from your local machine to host """ require('code_root', provided_by=('setup_env')) env.localsettings_path = settings.DJANGO_LOCALSETTINGS_LOCAL_PATH env.localsettings_destination = posixpath.join(env.code_root, settings.DJANGO_LOCALSETTINGS_REMOTE_DESTINATION) #note: relative to code_root _make_template_dict() with show('debug'): if(settings.DJANGO_LOCALSETTINGS_NO_TEMPLATE): put(env.localsettings_path, env.localsettings_destination) else: upload_template(env.localsettings_path, env.localsettings_destination, context=env.localsettings_dict, use_sudo=True)
[docs]def deploy(deploy_level="staging"): """ deploy code to remote host by checking out the latest via git """ setup_env(deploy_level) print green('In Django Module. Running deploy()...') sudo('echo ping!') #hack/workaround for delayed console response if env.environment == 'production': if not console.confirm('Are you sure you want to deploy production?', default=False): utils.abort('Production deployment aborted.') with cd(env.code_root): sudo('git checkout %(code_branch)s' % env, user=env.sudo_user) sudo('git pull', user=env.sudo_user) sudo('git submodule init', user=env.sudo_user) sudo('git submodule update', user=env.sudo_user) upload_localsettings() collectstatic()
[docs]def bootstrap(deploy_level="staging"): """ Creates initial folders, clones the git repo. DOES NOT DEPLOY() """ setup_env(deploy_level) print green('In Django Module. Running bootstrap()...') sudo('echo ping!') #hack/workaround for delayed console response if env.environment == 'production': if not console.confirm('Are you sure you want to deploy production?', default=False): utils.abort('Production deployment aborted.') setup_dirs() clone_repo() upload_localsettings()
[docs]def stop(): """ Does nothing in this module """ print green('In Django Module. Doing nothing for command stop().')
[docs]def start(): """ Does nothing in this module """ print green('In Django Module. Doing nothing for command start().')