7f135ee84956 — Peter Sanchez 12 years ago
Updated fabfile to a much more modern version
2 files changed, 125 insertions(+), 101 deletions(-)

M README.txt
M fabfile.py
M README.txt +7 -3
@@ 19,7 19,7 @@ It was written for Python 2.6+
 If you use a Python version less than 2.6 then please refer to this 
 URL:
 
-http://docs.fabfile.org/0.9.2/#documentation
+http://docs.fabfile.org/en/1.2.2/index.html#documentation
 
 You will need to add the following to your fabfile.py:
 

          
@@ 117,11 117,15 @@ Use
 
 Here is a basic deploy to the LOCAL machine:
 
-$ fab local setup
+$ fab space:local deploy:full
 
 Or say to the production environment:
 
-$ fab prod setup
+$ fab space:prod deploy:full
+
+Or say you just want to update the code and touch the WSGI handler:
+
+$ fab space:prod deploy:update
 
 
 TODO

          
M fabfile.py +118 -98
@@ 1,31 1,28 @@ 
 '''
-Original idea from:
-
-http://gist.github.com/571155
-
-Hacked it to basically be completely original.
-
+    Base fabric deploy. See README.txt
 '''
 import os
+from fabric.colors import red as _red
 from fabric.api import *
 
 
 # globals
-env.project_name = 'PROJECT_NAME'
+env.project_name = 'yourproject'
 env.run_south_migrate = True
 env.copy_base_settings_local = False
 env.num_releases = 7
+env.shell = '/bin/sh -c'
 
 
 # Environments
 def _is_local():
-    require('run_type', provided_by=[local, staging, prod])
+    require('run_type', provided_by=[space])
     return env.run_type == 'local'
 
 
 def _get_callable(default=run):
     'Return local or default (run) based on hosts variable'
-    require('run_type', provided_by=[local, staging, prod])
+    require('run_type', provided_by=[space])
     is_local = _is_local()
     if default == cd:
         return lcd if is_local else default

          
@@ 44,41 41,57 @@ def _get_cmds():
     )
 
 
-def localdev():
+def _localdev():
     'Use the local machine'
     env.hosts = ['localhost']
-    env.env_path = '/path/to/environments/PROJECT_NAME'
-    env.user = 'username'
+    env.env_path = '/Users/pjs/envs/yourproject'
+    env.user = 'pjs'
+    env.virtualhost_path = '/'
     env.run_type = 'local'
-    env.repo_path = '/path/to/local/repository'
+    env.repo_path = '/Users/pjs/development/yourproject'
     env.repo_rev = 'tip'
     env.copy_base_settings_local = True
 
 
-def staging():
+def _staging():
     'Use the staging environment'
     pass
 
 
-def prod():
+def _prod():
     'Use the production environment'
-    env.hosts = ['yourproject.yourdomain.com']
-    env.env_path = '/path/to/environments/PROJECT_NAME'
-    env.user = 'username'
+    env.hosts = ['your_production_host.com']
+    env.env_path = '/home/pjs/envs/yourproject'
+    env.user = 'pjs'
+    env.virtualhost_path = '/'
     env.run_type = 'prod'
-    env.repo_path = 'http://bitbucket.org/someuser/yourproject'
+    env.repo_path = 'http://bitbucket.org/youraccount/yourrepo'
     env.repo_rev = 'tip'
 
 
+# Tasks
+def space(envname='None'):
+    'Which environment? local, staging, or prod'
+    if envname == 'staging':
+        _staging()
+    elif envname == 'prod':
+        _prod()
+    elif envname == 'local':
+        _localdev()
+    else:
+        abort(_red('\n*** Invalid space variable passed: %s' % envname))
+
+
 def set_repo_revision(rev='tip'):
+    'Set repository revision to pull. Default: tip'
     env.repo_rev = rev
 
 
 def set_num_releases(amount=7):
-    env.num_releases = amount
+    'Set number of releases to save. Default: 7'
+    env.num_releases = int(amount)
 
 
-# Tasks
 def test():
     'Run the test suite and bail out if it fails'
     _run, _sudo, _cd = _get_cmds()

          
@@ 87,51 100,14 @@ def test():
         _run('python manage.py test')
 
 
-def setup():
-    '''
-    Setup a fresh virtualenv as well as a few useful directories, then run
-    a full deployment
-    '''
-    require('hosts', provided_by=[localdev, staging, prod])
-    require('env_path')
-    _run, _sudo, _cd = _get_cmds()
-    
-    import time
-    env.release = time.strftime('%Y%m%d%H%M%S')
-
-    lpath = '%(env_path)s/releases/%(release)s' % env
-    _run('mkdir -p %s' % lpath)
-    with _cd(lpath):
-        _run('virtualenv --no-site-packages .')
-        _run('mkdir -p shared packages')
-    deploy()
-
-
-def soft_update():
-    'Just update codebase. Do not do a full deploy'
-    require('hosts', provided_by=[localdev, staging, prod])
-    require('env_path')
-    
-    checkout_code_repo(update=True)
-    touch_wsgi_handler()
-
-
-def deploy():
-    '''
-    Deploy the latest version of the site to the servers, install any
-    required third party modules, install the virtual host and 
-    then restart the webserver
-    '''
-    require('hosts', provided_by=[localdev, staging, prod])
-    require('env_path')
-
-    checkout_code_repo()
-    install_requirements()
-    migrate()
-    install_site()
-    symlink_current_release()
-    restart_webserver()
-    remove_oldest_release()
+def deploy(dtype='None'):
+    'Deploy type? Options are: update, full'
+    if dtype == 'full':
+        _setup()
+    elif dtype == 'update':
+        _soft_update()
+    else:
+        abort(_red('\n*** Invalid deploy type given: %s' % dtype))
 
 
 def show_versions():

          
@@ 145,26 121,26 @@ def show_versions():
 
 def rollback_version(version):
     'Specify a specific version to be made live'
-    require('hosts', provided_by=[localdev, staging, prod])
+    require('hosts', provided_by=[space])
     require('env_path')
     _run, _sudo, _cd = _get_cmds()
     
     env.version = version
     with _cd('%(env_path)s' % env):
         _run('ln -nfs releases/%(version)s current' % env)
-    restart_webserver()
+    _restart_webserver()
 
 
 def rollback():
     'Simple GENERIC rollback. Symlink to the second most recent release'
-    require('hosts', provided_by=[localdev, staging, prod])
+    require('hosts', provided_by=[space])
     require('env_path')
     _run, _sudo, _cd = _get_cmds()
 
     releases = _get_releases_list()
     release = releases[-2]
     _run('ln -nfs releases/%s current' % release)
-    restart_webserver()
+    _restart_webserver()
 
 
 def fail_cleanup():

          
@@ 173,7 149,7 @@ def fail_cleanup():
     mess left behind. It will only remove the most recent 
     release directory. BE CAREFUL USING THIS.
     '''
-    require('hosts', provided_by=[localdev, staging, prod])
+    require('hosts', provided_by=[space])
     require('env_path')
     _run, _sudo, _cd = _get_cmds()
 

          
@@ 186,7 162,7 @@ def fail_cleanup():
 # Helpers. These are called by other functions rather than directly
 def _get_releases_list():
     'Returns sorted list of all current releases'
-    require('hosts', provided_by=[localdev, staging, prod])
+    require('hosts', provided_by=[space])
     require('env_path')
     _run, _sudo, _cd = _get_cmds()
 

          
@@ 196,10 172,44 @@ def _get_releases_list():
     return sorted(releases)
 
 
-def checkout_code_repo(update=False):
+def _setup():
+    '''
+    Setup a fresh virtualenv as well as a few useful directories, then run
+    a full deployment
+    '''
+    require('hosts', provided_by=[space])
+    require('env_path', provided_by=[space])
+    _run, _sudo, _cd = _get_cmds()
+
+    import time
+    env.release = time.strftime('%Y%m%d%H%M%S')
+
+    lpath = '%(env_path)s/releases/%(release)s' % env
+    _run('mkdir -p %s' % lpath)
+
+    _checkout_code_repo()
+    _make_virtual_environment()
+    _install_requirements()
+    _migrate()
+    _install_site()
+    _symlink_current_release()
+    _restart_webserver()
+    _remove_oldest_release()
+
+
+def _soft_update():
+    'Just update codebase. Do not do a full deploy'
+    require('hosts', provided_by=[space])
+    require('env_path')
+
+    _checkout_code_repo(update=True)
+    _touch_wsgi_handler()
+
+
+def _checkout_code_repo(update=False):
     'Create an archive from the current Git master branch and upload it'
-    require('repo_path', provided_by=[localdev, staging, prod])
-    require('repo_rev', provided_by=[localdev, staging, prod])
+    require('repo_path', provided_by=[space])
+    require('repo_rev', provided_by=[space])
     _run, _sudo, _cd = _get_cmds()
 
     if update:

          
@@ 207,7 217,7 @@ def checkout_code_repo(update=False):
         with _cd(lpath):
             _run('hg pull -r %(repo_rev)s -u' % env)
     else:
-        require('release', provided_by=[deploy, setup])
+        require('release', provided_by=[deploy])
         lpath = '%(env_path)s/releases/%(release)s' % env
         with _cd(lpath):
             cmd = 'hg clone -r '

          
@@ 221,77 231,87 @@ def checkout_code_repo(update=False):
                 _run('cp base_settings_local.py settings_local.py')
 
 
-def install_site():
+def _make_virtual_environment():
+    ' Create the virtualenv in the code repo '
+    require('release', provided_by=[deploy])
+    _run, _sudo, _cd = _get_cmds()
+
+    lpath = '%(env_path)s/releases/%(release)s/%(project_name)s' % env
+    with _cd(lpath):
+        _run('virtualenv --no-site-packages .')
+        _run('mkdir -p shared packages')
+
+
+def _install_site():
     'Add the virtualhost file to apache'
-    require('release', provided_by=[deploy, setup])
+    require('release', provided_by=[deploy])
     _run, _sudo, _cd = _get_cmds()
 
     if not _is_local():
         with _cd('%(env_path)s/releases/%(release)s' % env):
             cmd = 'cp %(project_name)s/apache/%(project_name)s.conf ' % env + \
-                  '/etc/apache2/conf.d/'
+                  '/usr/local/etc/apache22/Includes/'
             _sudo(cmd)
 
 
-def install_requirements():
+def _install_requirements():
     'Install the required packages from the requirements file using pip'
-    require('release', provided_by=[deploy, setup])
+    require('release', provided_by=[deploy])
     _run, _sudo, _cd = _get_cmds()
 
-    with _cd('%(env_path)s/releases/%(release)s' % env):
-        cmd = './bin/pip install -E . '
-        cmd += '-r ./%(project_name)s/requirements.txt ' % env
-        cmd += '--download-cache=~/.pipcache'
+    with _cd('%(env_path)s/releases/%(release)s/%(project_name)s' % env):
+        cmd = './bin/pip --timeout=1 install -E . '
+        cmd += '-r ./requirements.txt --download-cache=~/.pipcache'
         _run(cmd)
 
 
-def symlink_current_release():
+def _symlink_current_release():
     'Symlink our current release'
-    require('release', provided_by=[deploy, setup])
+    require('release', provided_by=[deploy])
     _run, _sudo, _cd = _get_cmds()
 
     with _cd('%(env_path)s' % env):
         _run('ln -nfs releases/%(release)s current' % env)
 
 
-def migrate():
+def _migrate():
     'Update the database'
     require('project_name')
-    require('release', provided_by=[deploy, setup])
+    require('release', provided_by=[deploy])
     _run, _sudo, _cd = _get_cmds()
 
     p = '%(env_path)s/releases/%(release)s/%(project_name)s/%(project_name)s' % env
     with _cd(p):
-        _run('../../bin/python manage.py syncdb --noinput')
+        _run('../bin/python manage.py syncdb --noinput')
         if env.run_south_migrate:
-            _run('../../bin/python manage.py migrate')
+            _run('../bin/python manage.py migrate')
 
 
-def restart_webserver():
+def _restart_webserver():
     'Restart the web server'
     _run, _sudo, _cd = _get_cmds()
 
     if not _is_local():
-        _sudo('apache2ctl configtest')
-        _sudo('service apache2 restart')
+        _sudo('/usr/local/etc/rc.d/apache22 configtest', pty=False)
+        _sudo('/usr/local/etc/rc.d/apache22 restart', pty=False)
 
 
-def touch_wsgi_handler():
+def _touch_wsgi_handler():
     'Touch the mod_wsgi wsgi_handler.py file'
     require('project_name')
-    require('hosts', provided_by=[localdev, staging, prod])
+    require('hosts', provided_by=[space])
     _run, _sudo, _cd = _get_cmds()
 
     with _cd('%(env_path)s/current/%(project_name)s/apache' % env):
         _run('touch wsgi_handler.py')
 
 
-def remove_oldest_release():
+def _remove_oldest_release():
     '''
     Remove oldest releases past the ammount passed 
     in with the "allow" variable. Default 7.
     '''
-    require('hosts', provided_by=[localdev, staging, prod])
+    require('hosts', provided_by=[space])
     require('num_releases')
     require('env_path')
     _run, _sudo, _cd = _get_cmds()