From: dsc Date: Wed, 9 May 2012 08:59:44 +0000 (-0700) Subject: Splits out staging. Finishes up on deploy. X-Git-Url: http://git.less.ly:3516/?a=commitdiff_plain;h=f91428e4b5835d45d5dca42a5cf2e6666049ee6b;p=limn-bak.git Splits out staging. Finishes up on deploy. --- diff --git a/fabfile/__init__.py b/fabfile/__init__.py index d720782..bb9bbaf 100644 --- a/fabfile/__init__.py +++ b/fabfile/__init__.py @@ -2,24 +2,25 @@ # -*- coding: utf-8 -*- "GraphKit Deployer" - import sys -from functools import wraps # Deal with the fact that we aren't *really* a Python project, # so we haven't declared python dependencies. try: from fabric.api import * - from path import path as p # fabric.api.path conflicts + from path import path as p # renamed to avoid conflict w/ fabric.api.path + import yaml except ImportError: print """ ERROR: You're missing a dependency! To build this project using fabric, you'll need to install fabric (and some other stuff): - pip install -U fabric path.py + pip install -U fabric path.py PyYAML """ sys.exit(1) +from util import * + ### Fabric Config @@ -37,6 +38,7 @@ env.minify_cmd = 'uglifyjs' env.dist = p('dist') env.local_tmp = p('tmp') env.work_dir = env.local_tmp/env.dist + env.browserify_js = 'vendor/browserify.js' env.work_browserify_js = env.work_dir/env.browserify_js env.vendor_search_dirs = map(p, ['static', 'var', env.work_dir]) @@ -45,15 +47,34 @@ env.app_bundle = env.work_dir/'js/kraken/app-bundle.js' env.app_bundle_min = p(env.app_bundle.replace('.js', '.min.js')) -# Rename to avoid conflicts when we make top-level wrapper tasks + +### Setup Staging Environments + +# We declare stubs here to use @task and have them show up at the top level +import stages + +@task +def prod(): + "Set deploy environment to production." + +@task +def stage(): + "Set deploy environment to stage." + stages.stage() + + + +### Project Tasks + import bundle import deploy @task(default=True) -def gogogo(): +def gogogoo(): """ Bundles and deploys the project. [Default] """ bundle.bundle_all() deploy.full_deploy() + diff --git a/fabfile/bundle.py b/fabfile/bundle.py index 81553c8..81c44c8 100644 --- a/fabfile/bundle.py +++ b/fabfile/bundle.py @@ -1,12 +1,12 @@ #!/usr/bin/env fab # -*- coding: utf-8 -*- +"Deploy Bundle Tasks" from fabric.api import * from fabric.colors import white, blue, cyan, green, yellow, red, magenta -from util import * +from util import * -### Build Deploy Bundle @task(default=True) def bundle_all(): diff --git a/fabfile/deploy.py b/fabfile/deploy.py index d3e71bc..c5ca070 100644 --- a/fabfile/deploy.py +++ b/fabfile/deploy.py @@ -1,77 +1,77 @@ #!/usr/bin/env fab # -*- coding: utf-8 -*- +"Deploy Tasks" + +from functools import wraps from fabric.api import * from fabric.colors import white, blue, cyan, green, yellow, red, magenta from fabric.contrib.project import rsync_project + +import stages from util import * -### Deploy Environments -# There should be a way to do this using stages. -# See: http://tav.espians.com/fabric-python-with-cleaner-api-and-parallel-deployment-support.html -# env.config_file = False -# env.stages = ['prod', 'staging'] +### Helpers -@task -def prod(): - """ Set deploy environment to production. - """ - env.deploy_env = 'prod' - env.hosts = ['reportcard2.pmtpa.wmflabs'] - env.target_dir = '/srv/reportcard/kraken-ui' - env.owner = 'www-data' - env.group = 'www' - -@task -def staging(): - """ Set deploy environment to staging. - """ - env.deploy_env = 'staging' - env.hosts = ['less.ly'] - env.target_dir = '/home/wmf/projects/kraken-ui' - env.user = 'wmf' - env.owner = 'wmf' - env.group = 'www' +def ensure_stage(fn): + "Decorator that ensures a stage is set." + + @wraps(fn) + def wrapper(*args, **kwargs): + if 'deploy_env' not in env: + abort(red('You must specify a staging environment (prod, stage) prior to deploy!', bold=True)) + return fn(*args, **kwargs) + + return wrapper ### Deploy Tasks @task(default=True) +@ensure_stage def full_deploy(): """ Deploy the project. """ - pass + fix_permissions() + update() + distribute() + fix_permissions() + restart_server() @task -def fix_permissions(): +@ensure_stage +def fix_permissions(user=None, group=None): """ Recursively fixes permissions on the deployment host. """ + if user is None: user = env.owner + if group is None: group = env.group sudo('chmod -R g+w %(target_dir)s' % env) - sudo('chown -R %(owner)s:%(group)s %(target_dir)s' % env) + sudo('chown -R %s:%s %s' % (user, group, env.target_dir)) @task +@ensure_stage def update(): """ Runs git pull on the deployment host. """ - with cd(env.target_dir): - run('git pull') + with cd(env.target_dir): run('git pull') @task +@ensure_stage def distribute(): """ Copies `dist` package to deployment host. """ + local("rsync -Caz -v %(work_dir)s %(user)s@%(host)s:%(target_dir)s/%(dist)s" % env) # TODO: make sure the following works. # rsync_project(local_dir=env.work_dir, remote_dir="%(user)s@%(host)s:%(target_dir)s/%(dist)s" % env) - local("rsync -Caz -v %(work_dir)s %(user)s@%(host)s:%(target_dir)s/%(dist)s" % env) @task +@ensure_stage def restart_server(): """ Restarts node.js server on the deployment host. """ - # need to work on this for less.ly - sudo("supervisor restart reportcard") + sudo("supervisorctl restart reportcard") diff --git a/fabfile/stages.py b/fabfile/stages.py new file mode 100644 index 0000000..ebada51 --- /dev/null +++ b/fabfile/stages.py @@ -0,0 +1,40 @@ +#!/usr/bin/env fab +# -*- coding: utf-8 -*- +"Setup Staging Environments" + +from fabric.api import env + +__all__ = ('prod', 'stage',) + +# (otto) There should be a way to do this using stages. +# See: http://tav.espians.com/fabric-python-with-cleaner-api-and-parallel-deployment-support.html +# (dsc) ...except that most of those changes are not actually in Fabric :( + +# env.config_file = False +# env.stages = ['prod', 'staging'] + + +# NOTE WELL: These do not have @task as they'd show up as "stages.prod", +# and we want them at the top level. See __init__.py for the wrappers. +# Unfortunately, we can't put them in __init__.py without preventing deploy.py +# from importing them. + +def prod(): + """ Set deploy environment to production. + """ + env.deploy_env = 'prod' + env.hosts = ['reportcard2.pmtpa.wmflabs'] + env.target_dir = '/srv/reportcard/kraken-ui' + env.owner = 'www-data' + env.group = 'www' + +def stage(): + """ Set deploy environment to stage. + """ + env.deploy_env = 'stage' + env.hosts = ['less.ly'] + env.target_dir = '/home/wmf/projects/kraken-ui' + env.user = 'wmf' + env.owner = 'wmf' + env.group = 'www' + diff --git a/fabfile/util.py b/fabfile/util.py index b61d664..befa087 100644 --- a/fabfile/util.py +++ b/fabfile/util.py @@ -8,7 +8,7 @@ from functools import wraps from fabric.api import * from fabric.colors import white, blue, cyan, green, yellow, red, magenta -__all__ = ('quietly', 'msg', 'coke', 'update_version',) +__all__ = ('quietly', 'msg', 'make_wrapper', 'coke', 'update_version',) @contextmanager @@ -38,6 +38,7 @@ def msg(txt, quiet=False): return outer + ### Misc def coke(args, capture=False):