1 from __future__ import with_statement # needed for python 2.5
2 from fabric.api import *
3 from fabric.contrib import files
4 from fabric.context_managers import path
13 env.project_name = 'wolnelektury'
18 """Use staging server"""
19 env.hosts = ['stigma.nowoczesnapolska.org.pl:2222']
20 env.user = 'platforma'
21 env.path = '/var/services/wolnelektury'
22 env.python = '/usr/bin/python'
23 env.virtualenv = '/usr/bin/virtualenv'
24 env.pip = '/usr/bin/pip'
27 """Use production server"""
28 env.hosts = ['wolnelektury.pl']
30 env.path = '/srv/wolnelektury.pl'
31 env.python = '/usr/bin/python'
32 env.virtualenv = '/usr/bin/virtualenv'
33 env.pip = 've/bin/pip'
34 env.restart_webserver = restart_gunicorn_debian
40 "Run the test suite and bail out if it fails"
41 require('hosts', 'path', provided_by=[staging, production])
42 result = run('cd %(path)s/%(project_name)s; %(python)s manage.py test' % env)
46 Setup a fresh virtualenv as well as a few useful directories, then run
47 a full deployment. virtualenv and pip should be already installed.
49 require('hosts', 'path', provided_by=[staging, production])
51 run('mkdir -p %(path)s; cd %(path)s; %(virtualenv)s .;' % env, pty=True)
52 run('cd %(path)s; mkdir releases; mkdir shared; mkdir packages;' % env, pty=True)
53 run('cd %(path)s/releases; ln -s . current; ln -s . previous' % env, pty=True)
58 Deploy the latest version of the site to the servers,
59 install any required third party modules,
60 install the virtual host and then restart the webserver
62 require('hosts', 'path', provided_by=[staging, production])
65 env.release = time.strftime('%Y-%m-%dT%H%M')
71 install_requirements()
73 symlink_current_release()
79 def deploy_version(version):
80 "Specify a specific version to be made live"
81 require('hosts', 'path', provided_by=[localhost,webserver])
84 run('rm releases/previous; mv releases/current releases/previous;', pty=True)
85 run('ln -s %(version)s releases/current' % env, pty=True)
91 Limited rollback capability. Simple loads the previously current
92 version of the code. Rolling back again will swap between the two.
94 require('hosts', provided_by=[staging, production])
97 run('mv releases/current releases/_previous;', pty=True)
98 run('mv releases/previous releases/current;', pty=True)
99 run('mv releases/_previous releases/previous;', pty=True)
104 # =====================================================================
105 # = Helpers. These are called by other functions rather than directly =
106 # =====================================================================
107 def upload_tar_from_git():
108 "Create an archive from the current Git branch and upload it"
109 print '>>> upload tar from git'
110 require('release', provided_by=[deploy])
111 local('git-archive-all.sh --format tar %(release)s.tar' % env)
112 local('gzip %(release)s.tar' % env)
113 run('mkdir -p %(path)s/releases/%(release)s' % env, pty=True)
114 run('mkdir -p %(path)s/packages' % env, pty=True)
115 put('%(release)s.tar.gz' % env, '%(path)s/packages/' % env)
116 run('cd %(path)s/releases/%(release)s && tar zxf ../../packages/%(release)s.tar.gz' % env, pty=True)
117 local('rm %(release)s.tar.gz' % env)
119 def upload_vhost_sample():
120 "Create and upload Apache virtual host configuration sample"
121 print ">>> upload vhost sample"
122 files.upload_template('%(project_name)s.vhost.template' % env, '%(path)s/%(project_name)s.vhost.sample' % env, context=env)
124 def upload_wsgi_script():
125 "Create and upload a wsgi script sample"
126 print ">>> upload wsgi script sample"
127 files.upload_template('%(project_name)s.wsgi.template' % env, '%(path)s/%(project_name)s.wsgi' % env, context=env)
128 run('chmod ug+x %(path)s/%(project_name)s.wsgi' % env)
130 def upload_celery_conf():
131 "Create and upload a Celery conf for supervisord"
132 print ">>> upload celery supervisord conf"
133 files.upload_template('%(project_name)s-celery.conf.template' % env, '%(path)s/%(project_name)s-celery.conf' % env, context=env)
134 run('chmod ug+x %(path)s/%(project_name)s-celery.conf' % env)
136 def install_requirements():
137 "Install the required packages from the requirements file using pip"
138 print '>>> install requirements'
139 require('release', provided_by=[deploy])
140 run('cd %(path)s; %(pip)s install -E ve -r %(path)s/releases/%(release)s/requirements.txt' % env, pty=True)
142 def copy_localsettings():
143 "Copy localsettings.py from root directory to release directory (if this file exists)"
144 print ">>> copy localsettings"
145 require('release', provided_by=[deploy])
146 require('path', provided_by=[staging, production])
148 with settings(warn_only=True):
149 run('cp %(path)s/localsettings.py %(path)s/releases/%(release)s/%(project_name)s' % env)
151 def symlink_current_release():
152 "Symlink our current release"
153 print '>>> symlink current release'
154 require('release', provided_by=[deploy])
155 require('path', provided_by=[staging, production])
157 run('rm releases/previous; mv releases/current releases/previous')
158 run('ln -s %(release)s releases/current' % env)
161 "Update the database"
163 require('project_name', provided_by=[staging, production])
164 with cd('%(path)s/releases/current/%(project_name)s' % env):
165 run('../../../ve/bin/python manage.py syncdb --noinput' % env, pty=True)
167 run('../../../ve/bin/python manage.py migrate' % env, pty=True)
170 """Collect static files"""
171 print '>>> collectstatic'
172 require('project_name', provided_by=[staging, production])
173 with cd('%(path)s/releases/current/%(project_name)s' % env):
174 run('../../../ve/bin/python manage.py collectstatic --noinput' % env, pty=True)
176 def restart_gunicorn_debian():
177 """Restarts gunicorn server using debian script."""
178 print '>>> restart gunicorn'
179 require('project_name', provided_by=[staging, production])
181 sudo('gunicorn-debian restart %(project_name)s' % env, shell=False)
183 def restart_webserver():
184 """Restarts the web server."""
185 if hasattr(env, 'restart_webserver'):
186 env.restart_webserver()
188 require('project_name', provided_by=[staging, production])
189 print '>>> restart webserver'
190 run('touch %(path)s/%(project_name)s.wsgi' % env)
192 def restart_celery():
193 """Restarts the Celery task queue manager."""
194 print '>>> restart Celery'
195 require('project_name', provided_by=[staging, production])
196 sudo('supervisorctl restart celery.%(project_name)s:' % env, shell=False)