+# -*- coding: utf-8 -*-
"""
Generic fabric deployment script.
Create a fabfile.py in the project and start it with:
"""
from subprocess import check_output
from os.path import abspath, dirname, exists, join
-from fabric.api import *
+from fabric.api import env, task, require, run, cd, abort, sudo, path, local, put
from fabric.context_managers import settings
from fabric.contrib import files
from fabric.tasks import Task, execute
collectstatic()
restart()
+
@task
def rollback():
"""
collectstatic()
restart()
+
@task
def deploy_version(version):
"""
collectstatic()
restart()
+
@task
def restart():
for service in env.services or ():
def upload_sample(self):
pass
+ def run(self):
+ raise NotImplementedError
+
+
class DebianGunicorn(Service):
def __init__(self, name):
super(Task, self).__init__()
with settings(full_django_root=get_django_root_path('current')):
upload_sample('gunicorn')
+
class Apache(Service):
def run(self):
print '>>> restart webserver by touching WSGI'
with path('/sbin'):
run('touch %(app_path)s/%(project_name)s/wsgi.py' % env)
+
class Supervisord(Service):
def __init__(self, name):
super(Task, self).__init__()
print '>>> supervisord: restart %s' % self.name
sudo('supervisorctl restart %s' % self.name, shell=False)
+
class Command(Task):
def __init__(self, commands, working_dir):
+ super(Task, self).__init__()
if not hasattr(commands, '__iter__'):
commands = [commands]
self.name = 'Command: %s @ %s' % (commands, working_dir)
for command in self.commands:
run(command)
+
def upload_samples():
upload_localsettings_sample()
upload_nginx_sample()
for service in env.services:
service.upload_sample()
+
def upload_sample(name, where="samples/", ext='.sample', **kwargs):
require('app_path', 'project_name')
upload_path = '%s/%s%s%s' % (env['app_path'], where, name, ext)
template = join(dirname(abspath(__file__)), 'templates/' + name + '.template')
files.upload_template(template, upload_path, env, **kwargs)
+
def upload_localsettings_sample():
- "Fill out localsettings template and upload as a sample."
+ """Fill out localsettings template and upload as a sample."""
env.secret_key = get_random_string(50)
upload_sample('localsettings.py', where="")
-upload_nginx_sample = lambda: upload_sample('nginx')
+
+def upload_nginx_sample():
+ upload_sample('nginx')
+
def upload_tar_from_git():
- "Create an archive from the current Git branch and upload it"
+ """Create an archive from the current Git branch and upload it"""
print '>>> upload tar from git'
require('release', provided_by=[deploy])
require('app_path')
run('cd %(app_path)s/releases/%(release)s && tar zxf ../../packages/%(release)s.tar.gz' % env, pty=True)
local('rm %(release)s.tar.gz' % env)
+
def install_requirements():
- "Install the required packages from the requirements file using pip"
+ """Install the required packages from the requirements file using pip"""
print '>>> install requirements'
require('release', provided_by=[deploy])
require('app_path')
require('virtualenv')
run('%(virtualenv)s %(ve)s' % env, pty=True)
with cd('%(app_path)s/releases/%(release)s' % env):
- run('%(ve)s/bin/pip install -r %(reqs)s' % {'ve': env.ve, 'reqs': env.get('requirements_file', 'requirements.txt')}, pty=True)
+ run('%(ve)s/bin/pip install -r %(reqs)s' % {
+ 've': env.ve, 'reqs': env.get('requirements_file', 'requirements.txt')}, pty=True)
with cd(get_django_root_path(env['release'])):
# Install DB requirement
database_reqs = {
def copy_localsettings():
- "Copy localsettings.py from root directory to release directory (if this file exists)"
+ """Copy localsettings.py from root directory to release directory (if this file exists)"""
print ">>> copy localsettings"
require('release', provided_by=[deploy])
require('app_path', 'project_name')
copy_to = join(get_django_root_path(env['release']), env.get('localsettings_dst_path', env['project_name']))
run('cp %(app_path)s/localsettings.py ' % env + copy_to)
+
def symlink_current_release():
- "Symlink our current release"
+ """Symlink our current release"""
print '>>> symlink current release'
require('release', provided_by=[deploy])
require('app_path')
run('rm releases/previous; mv releases/current releases/previous')
run('ln -s %(release)s releases/current' % env)
+
def migrate():
- "Update the database"
+ """Update the database"""
print '>>> migrate'
require('app_path', 'project_name')
with cd(get_django_root_path('current')):
run('%s/bin/python manage.py migrate %s --fake %s' % (env.ve, app, migration), pty=True)
run('%(ve)s/bin/python manage.py migrate' % env, pty=True)
+
def pre_collectstatic():
print '>>> pre_collectstatic'
for task in env.get('pre_collectstatic', []):
execute(task)
+
def collectstatic():
"""Collect static files"""
print '>>> collectstatic'
with cd(get_django_root_path('current')):
run('%(ve)s/bin/python manage.py collectstatic --noinput' % env, pty=True)
+
def get_django_root_path(release):
require('app_path')
- path = '%(app_path)s/releases/%(release)s' % dict(app_path = env['app_path'], release = release)
+ path = '%(app_path)s/releases/%(release)s' % dict(app_path=env['app_path'], release=release)
if 'django_root_path' in env:
path = join(path, env['django_root_path'])
return path
+
def set_ve():
if 've' not in env:
env['ve'] = '%s/ve' % env.app_path