1 from __future__ import with_statement # needed for python 2.5
2 from fabric.api import *
3 from fabric.contrib import files
12 env.project_name = 'platforma'
14 env.giturl = "git://github.com/fnp/redakcja.git"
19 """Use staging server"""
20 env.hosts = ['stigma.nowoczesnapolska.org.pl:2222']
21 env.user = 'platforma'
22 env.path = '/var/services/platforma'
23 env.python = '/usr/bin/python'
24 env.virtualenv = '/usr/bin/virtualenv'
25 env.pip = '/usr/bin/pip'
26 env.gitbranch = "staging"
31 """Use production server"""
32 env.hosts = ['szo.nowoczesnapolska.org.pl:2225']
33 env.user = 'librarian'
34 env.gitbranch = 'master'
35 env.sandbox = '/srv/library-in-a-box/sandbox/'
36 env.virtualenv = os.path.join(env.sandbox, 'bin', 'virtualenv')
38 env.pip = os.path.join(env.sandbox, 'python', 'bin', 'pip')
39 env.python = os.path.join(env.sandbox, 'python', 'bin', 'python')
44 env.path = os.path.join(env.sandbox, env.project_name)
45 env.target = os.path.join(env.path, 'bin', 'python')
52 "Run the test suite and bail out if it fails"
53 require('hosts', 'path', provided_by=[staging, production])
54 result = run('cd %(path)s/%(project_name)s; %(python)s manage.py test' % env)
59 Setup a fresh virtualenv as well as a few useful directories, then run
60 a full deployment. virtualenv and pip should be already installed.
62 require('hosts', 'sandbox', provided_by=[staging, production])
64 run("mkdir -p %(path)s; mkdir -p %(path)s/www/wsgi; mkdir -p %(path)s/www/media" % env)
68 git clone %(giturl)s mirror;
70 git pull""" % env, pty=True)
72 run('%(virtualenv)s %(path)s' % env, pty=True)
73 run('cd %(path)s; rm -rf releases shared packages; mkdir -p releases; mkdir -p shared; mkdir -p packages;' % env, pty=True)
75 # symlink static content
76 run("""cd %(path)s/www/media;
77 ln -sf %(path)s/releases/current/%(project_name)s/static static
78 ln -sf %(path)s/lib/python2.6/site-packages/django/contrib/admin/media admin-media
82 run('cd %(path)s/releases; ln -s . current; ln -s . previous' % env, pty=True)
89 Deploy the latest version of the site to the servers,
90 install any required third party modules,
91 install the virtual host and then restart the webserver
93 require('hosts', 'sandbox', 'gitbranch', provided_by=[staging, production])
95 env.release = time.strftime('%Y-%m-%dT%H%M')
97 prepare_package_from_git()
100 # upload_vhost_sample()
101 install_requirements()
102 hardlink_localsettings()
103 symlink_current_release()
109 def deploy_version(version):
110 "Specify a specific version to be made live"
111 require('hosts', 'path', provided_by=[localhost, webserver])
112 env.version = version
114 run('rm releases/previous; mv releases/current releases/previous;', pty=True)
115 run('ln -s %(version)s releases/current' % env, pty=True)
122 Limited rollback capability. Simple loads the previously current
123 version of the code. Rolling back again will swap between the two.
125 require('hosts', provided_by=[staging, production])
128 run('mv releases/current releases/_previous;', pty=True)
129 run('mv releases/previous releases/current;', pty=True)
130 run('mv releases/_previous releases/previous;', pty=True)
134 # =====================================================================
135 # = Helpers. These are called by other functions rather than directly =
136 # =====================================================================
137 def prepare_package_from_git():
138 "Create an archive from the current Git master branch and upload it"
139 print '>>> upload tar from git'
141 require('release', provided_by=[deploy])
143 run('mkdir -p %(path)s/releases/%(release)s' % env, pty=True)
144 run('mkdir -p %(path)s/packages' % env, pty=True)
145 run('cd %(path)s/mirror; git pull; git archive --format=tar %(gitbranch)s | gzip > %(path)s/packages/%(release)s.tar.gz' % env)
146 run('cd %(path)s/releases/%(release)s && tar zxf ../../packages/%(release)s.tar.gz' % env, pty=True)
149 #def upload_vhost_sample():
150 # "Create and upload Apache virtual host configuration sample"
151 # print ">>> upload vhost sample"
152 # files.upload_template('%(project_name)s.vhost.template' % env, '%(path)s/%(project_name)s.vhost.sample' % env, context=env)
155 def upload_wsgi_script():
156 "Create and upload a wsgi script sample"
157 print ">>> upload wsgi script sample"
158 files.upload_template('%(project_name)s/config/%(project_name)s.wsgi.template' % env, '%(path)s/www/wsgi/%(project_name)s.wsgi' % env, context=env)
159 run('chmod ug+x %(path)s/www/wsgi/%(project_name)s.wsgi' % env)
162 def install_requirements():
163 "Install the required packages from the requirements file using pip"
165 print '>>> Instaling global requirements'
166 require('release', provided_by=[deploy])
167 run('cd %(path)s; %(path)s/bin/pip install -r %(path)s/releases/%(release)s/%(project_name)s/config/requirements.txt' % env, pty=True)
169 print '>>> Instaling site requirements'
171 with settings(warn_only=True):
172 run('cd %(path)s; %(path)s/bin/pip install -r %(sandbox)s/etc/%(project_name)s/requirements.txt' % env, pty=True)
175 def hardlink_localsettings():
176 "Hardlink localsettings.py from root directory to release directory (if this file exists)"
177 print ">>> Hardlink localsettings"
178 require('release', 'path', provided_by=[deploy])
179 require('sandbox', provided_by=[staging, production])
181 # hardlink localsettings
182 with settings(warn_only=True):
183 run('ln %(sandbox)s/etc/%(project_name)s/localsettings.py %(path)s/releases/%(release)s/%(project_name)s' % env)
186 def symlink_current_release():
187 "Symlink our current release"
188 print '>>> symlink current release'
189 require('release', provided_by=[deploy])
190 require('path', provided_by=[staging, production])
192 run('rm releases/previous; mv releases/current releases/previous')
193 run('ln -s %(release)s releases/current' % env)
197 "Update the database"
199 require('project_name', provided_by=[staging, production])
200 with cd('%(path)s/releases/current/%(project_name)s' % env):
201 run('%(target)s manage.py syncdb --noinput' % env, pty=True)
204 run('%(target)s manage.py migrate' % env, pty=True)
207 def django_compress():
208 "Update static files"
210 require('project_name', provided_by=[staging, production])
211 with cd('%(path)s/releases/current/%(project_name)s' % env):
212 run('%(target)s manage.py synccompress --force' % env, pty=True)
215 def restart_webserver():
216 "Restart the web server"
217 print '>>> restart webserver'
218 run('touch %(path)s/www/wsgi/%(project_name)s.wsgi' % env)