Source

eyes / fabfile.py

Full commit
#!/usr/bin/env python
from __future__ import with_statement # needed for python 2.5
from fabric.api import *
from fabric.contrib.console import confirm
from fabric.contrib import files

USAGE = """
================================================================
NOTE: 
   using this fabfile expects that you have the python utility
fabric installed locally, ssh access to your Eyes server, and 
your ssh public key associated with the account 'mboza' on your
Eyes server
================================================================
USAGE:

* fab help 
   prints this command
   
* fab test
   runs the embedded unit and smoke tests for the model in the
   development environment. Called from deploy() as a pass/fail
   step in the deployment process.
   
* fab linode background_setup 
   install the ubuntu/debian based packages needed for Apache,
   mod_wsgi, etc to support our pinax-based project

* fab linode setup 
   establish a python virtual environment in the worker directory

* fab linode deploy 
   deploys the contents of your current mercurial repository up
   to soulcraft.com and pushes out the prototype dir into 
   /var/www for immediate viewing

* fab linode initialize
   ONLY RUN ONCE FOR THE SITE - initializes a superuser account
   and sets the admin password
================================================================
"""

# GLOBALS
 
env.path = '/tmp'
env.project_name = 'eyes'

# ENVIRONMENTS
    
def linode():
    """
    Configure for the host at linode.
    """
    env.hosts = ['eyes.yourserver.com']
    env.user = 'mboza'
    env.user_home = '/home/mboza'
    env.use_photologue = False
     
# COMMANDS

def help():
    print USAGE

def background_setup():
    require('hosts', provided_by=[linode])
    apt_install('apache2')
    apt_install('libapache2-mod-wsgi')
    apt_install('python-mysqldb')
    apt_install('python-imaging')
    apt_install('build-essential')
    apt_install('python-dev')
    apt_install('python-setuptools')
    apt_install('python-virtualenv')
    easy_install('pip')
    #sudo('cd /etc/apache2/sites-available/; a2dissite default;', pty=True)
        
def setup():
    require('hosts', provided_by=[linode])
    require('path')
    require('user_home', provided_by=[linode])
    cd(env.user_home)
    run('virtualenv --clear .', pty=True)
    with cd(env.user_home):
        if env.use_photologue: run('mkdir photologue');
    if not files.exists('/var/log/django'):
        sudo('mkdir /var/log/django')
        sudo('chown %(user)s /var/log/django' % env)
    upload_tar_from_hg()
    install_requirements()

def prototype():    
    require('hosts', provided_by=[linode])

    upload_tar_from_hg()
    deploy_var_www()
    
def deploy():
    require('hosts', provided_by=[linode])
    test()
    upload_tar_from_hg()
    install_requirements()
    deploy_home_mboza()

def initialize():
    with cd(env.user_home):
        with_virtualenv('python soulcraft/manage.py createsuperuser --username=admin --email=admin@somewhere.com --noinput')
        with_virtualenv('python soulcraft/setsuperuserpassword.py')    

def test():
    results = []
    with settings(warn_only=True):
        with cd('src/soulcraft'):
            results.append(local('./manage.py test origins registration', capture=False))
    print results
    for result in results:
        if result.failed:
            if not confirm("Tests failed. Continue anyway?"):
                abort("Aborting at user request.")
    
def deploy_var_www():
    """
    Deploy the project onto the target environment.
    """
    require('hosts', provided_by=[linode])
    require('path')
    
    with cd('%(path)s/archive/prototype' % env):
        run('tar cvf /tmp/vw.tar .', pty=True)
    with cd('/var/www/'):
        run('tar xvf /tmp/vw.tar', pty=True)
    run ('rm -f /tmp/vw.tar')
    
def deploy_home_mboza():
    """
    Assumes setup_home_mboza() has already been run.
    """
    require('hosts', provided_by=[linode])
    require('path')
    
    with cd('%(path)s/archive/src' % env):
        run('tar cvf /tmp/dj.tar .', pty=True)
    with cd('%(user_home)s' % env):
        run('tar xvf /tmp/dj.tar', pty=True)
    run ('rm -f /tmp/dj.tar')
    cd('%(user_home)s' % env)
    install_site()
    install_logrotate()
    migrate()
    restart_webserver()

def migrate():
    "Update the database"
    require('project_name')
    require('user_home')
    run('cd %(user_home)s/%(project_name)s;  python manage.py syncdb --noinput' % env, pty=True)
    run('cd %(user_home)s/%(project_name)s;  python manage.py migrate' % env, pty=True)

def restart_webserver():
    "Restart the web server"
    sudo('/etc/init.d/apache2 reload', pty=True)
    

def install_site():
    "Add the virtualhost file to apache"
    sudo('cd %(user_home)s/eyes/deploy; cp eyes /etc/apache2/sites-available/%(project_name)s' % env)
    sudo('cd /etc/apache2/sites-available/; a2ensite %(project_name)s' % env, pty=True) 

def install_logrotate():
    pass

# UTILITIES
 
def upload_tar_from_hg():
    """
    Create a tar archive from the current hg master branch and upload it.
    """    
    local('hg archive -t tgz /tmp/archive.tgz', capture=False)
    put('/tmp/archive.tgz', '%(path)s' % env)

    with cd(env.path):
        run('tar zxf archive.tgz', pty=True)
        
    local('rm /tmp/archive.tgz')
    
def apt_install(package):
    """
    Install a single package on the remote server with Apt.
    """
    sudo('aptitude install -y %s' % package)
 
def easy_install(package):
    """
    Install a single package on the remote server with easy_install.
    """
    sudo('easy_install %s' % package)
 
def pip_install(package):
    """
    Install a single package on the remote server with pip.
    """
    sudo('pip install %s' % package)

def with_virtualenv(command):
    """
    Executes a command in this project's virtual environment.
    """
    run('source bin/activate && %s' % command)
 
def install_requirements():
    """
    Install the required packages from the requirements file using pip.
    """    
    with cd(env.user_home):
        with_virtualenv('pip install -r /tmp/archive/requirements.txt')