1 from __future__ import with_statement # needed for python 2.5
2 from fabric.api import *
3 from fabric.contrib.files import upload_template
12 env.project_name = 'platforma'
17 """Use staging server"""
18 env.hosts = ['stigma.nowoczesnapolska.org.pl:2222']
20 env.path = '/var/services/platforma'
21 env.python = '/usr/bin/python'
22 env.virtualenv = '/usr/bin/virtualenv'
23 env.pip = '/usr/bin/pip'
26 """Use production server"""
27 env.hosts = ['wolnelektury.pl:22123']
29 env.path = '/opt/lektury/platforma'
30 env.python = '/opt/lektury/basevirtualenv/bin/python'
31 env.virtualenv = '/opt/lektury/basevirtualenv/bin/virtualenv'
32 env.pip = '/opt/lektury/basevirtualenv/bin/pip'
39 "Run the test suite and bail out if it fails"
40 require('hosts', 'path', provided_by=[staging, production])
41 result = run('cd %(path)s/%(project_name)s; %(python)s manage.py test' % env)
45 Setup a fresh virtualenv as well as a few useful directories, then run
46 a full deployment. virtualenv and pip should be already installed.
48 require('hosts', 'path', provided_by=[staging, production])
50 run('mkdir -p %(path)s; cd %(path)s; %(virtualenv)s --no-site-packages .;' % env, pty=True)
51 run('cd %(path)s; mkdir releases; mkdir shared; mkdir packages;' % env, pty=True)
52 run('cd %(path)s/releases; ln -s . current; ln -s . previous' % env, pty=True)
57 Deploy the latest version of the site to the servers,
58 install any required third party modules,
59 install the virtual host and then restart the webserver
61 require('hosts', 'path', provided_by=[staging, production])
64 env.release = time.strftime('%Y-%m-%dT%H%M')
68 install_requirements()
69 upload_wsgi_script_sample()
70 symlink_current_release()
74 def deploy_version(version):
75 "Specify a specific version to be made live"
76 require('hosts', 'path', provided_by=[localhost,webserver])
79 run('rm releases/previous; mv releases/current releases/previous;', pty=True)
80 run('ln -s %(version)s releases/current' % env, pty=True)
85 Limited rollback capability. Simple loads the previously current
86 version of the code. Rolling back again will swap between the two.
88 require('hosts', provided_by=[staging, production])
91 run('mv releases/current releases/_previous;', pty=True)
92 run('mv releases/previous releases/current;', pty=True)
93 run('mv releases/_previous releases/previous;', pty=True)
97 # =====================================================================
98 # = Helpers. These are called by other functions rather than directly =
99 # =====================================================================
100 def upload_tar_from_git():
101 "Create an archive from the current Git master branch and upload it"
102 print '>>> upload tar from git'
103 require('release', provided_by=[deploy])
104 local('git archive --format=tar master | gzip > %(release)s.tar.gz' % env)
105 run('mkdir -p %(path)s/releases/%(release)s' % env, pty=True)
106 run('mkdir -p %(path)s/packages' % env, pty=True)
107 put('%(release)s.tar.gz' % env, '%(path)s/packages/' % env)
108 run('cd %(path)s/releases/%(release)s && tar zxf ../../packages/%(release)s.tar.gz' % env, pty=True)
109 local('rm %(release)s.tar.gz' % env)
111 def install_requirements():
112 "Install the required packages from the requirements file using pip"
113 print '>>> install requirements'
114 require('release', provided_by=[deploy])
115 run('cd %(path)s; %(pip)s install -E . requirements.pybundle' % env)
117 def upload_pybundle():
118 "Create pybundle with required libraries and upload it"
119 print ">>> upload pybundle"
120 require('release', provided_by=[deploy])
121 with settings(warn_only=True):
122 pip_options = run('cat %(path)s/releases/%(release)s/pip-options.txt' % env)
123 if pip_options.failed:
126 env.pip_options = pip_options
128 requirements_mtime = os.path.getmtime('requirements.txt')
131 bundle_mtime = os.path.getmtime('requirements.pybundle')
135 if requirements_mtime > bundle_mtime:
136 local('pip bundle requirements.pybundle %(pip_options)s -r requirements.txt' % env)
137 put('requirements.pybundle', '%(path)s' % env)
139 def upload_wsgi_script_sample():
140 "Create and upload a wsgi script sample"
141 print ">>> upload wsgi script sample"
143 upload_template('%(project_name)s.wsgi.template' % env, '%(path)s/%(project_name)s.wsgi.sample' % env, context=env)
145 def symlink_current_release():
146 "Symlink our current release"
147 print '>>> symlink current release'
148 require('release', provided_by=[deploy])
149 require('path', provided_by=[staging, production])
151 run('rm releases/previous; mv releases/current releases/previous')
152 run('ln -s %(release)s releases/current' % env)
155 "Update the database"
157 require('project_name', provided_by=[staging, production])
158 with cd('%(path)s/releases/current/%(project_name)s' % env):
159 run('../../../bin/python manage.py syncdb --noinput' % env, pty=True)
161 run('../../../bin/python manage.py migrate' % env, pty=True)
163 def restart_webserver():
164 "Restart the web server"
165 print '>>> restart webserver'
166 run('touch %(path)s/releases/current/%(project_name)s/%(project_name)s.wsgi' % env)