Updates deployer with new targets for test-reportcard and dev-reportcard, allows...
authordsc <dsc@less.ly>
Mon, 14 May 2012 20:19:23 +0000 (13:19 -0700)
committerdsc <dsc@less.ly>
Mon, 14 May 2012 20:19:23 +0000 (13:19 -0700)
fabfile/__init__.py
fabfile/deploy.py
fabfile/stages.py

index f4aaad9..e13d825 100644 (file)
@@ -3,6 +3,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.
@@ -31,21 +33,27 @@ from util import *
 ### Fabric Config
 
 # TODO: env.rcfile = 'fabfile/fabricrc.conf'
-env.project_name       = 'kraken-ui'
-env.colors             = True
-env.use_ssh_config     = True
-
-
-### Project Config
 
-env.dev_server         = 'localhost:8081'
-env.minify_cmd         = 'uglifyjs'
+# We `update()` here so --set on the commandline will override.
+for k, v in dict(
+    project_name       = 'kraken-ui',
+    colors             = True,
+    use_ssh_config     = True,
+    
+    dev_server         = 'localhost:8081',
+    minify_cmd         = 'uglifyjs',
+    
+    dist               = 'dist',
+    local_tmp          = 'tmp',
+    browserify_js      = 'vendor/browserify.js',
+    supervisor_job     = 'reportcard',
+).iteritems():
+    env.setdefault(k, v)
+
+for k in ('dist', 'local_tmp',):
+    env[k] = p(env[k])
 
-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])
 env.vendor_bundle      = env.work_dir/'vendor/vendor-bundle.min.js'
@@ -53,22 +61,14 @@ env.app_bundle         = env.work_dir/'js/kraken/app-bundle.js'
 env.app_bundle_min     = p(env.app_bundle.replace('.js', '.min.js'))
 
 
-
 ### Setup Staging Environments
 
 # Envs aren't declared with @task in the stages module so that we can
 # decorate them here and have them show up at the top level.
 import stages
 
-@task
-def prod():
-    "Set deploy environment to production."
-    stages.prod()
-
-@task
-def stage():
-    "Set deploy environment to stage."
-    stages.stage()
+for name in stages.NAMES:
+    globals()[name] = task(getattr(stages, name))
 
 
 
@@ -78,7 +78,7 @@ import bundle
 import deploy
 
 @task(default=True)
-@stages.ensure_stage
+@stages.prompt_for_stage
 def full_deploy():
     """ Bundles and deploys the project. [Default]
     """
index 2139204..4111088 100644 (file)
@@ -53,6 +53,6 @@ def sync_files():
 def restart_node():
     """ Restarts node.js server on the deployment host.
     """
-    sudo("supervisorctl restart reportcard")
+    sudo("supervisorctl restart %(supervisor_job)s" % env)
 
 
index 0140fef..2b58c72 100644 (file)
@@ -2,11 +2,12 @@
 # -*- coding: utf-8 -*-
 "Setup Staging Environments"
 
+import sys
 from functools import wraps
-from fabric.api import env, abort
+from fabric.api import env, abort, prompt, execute
 from fabric.colors import white, blue, cyan, green, yellow, red, magenta
 
-__all__ = ('prod', 'stage', 'ensure_stage',)
+__all__ = ['NAMES', 'validate_stage', 'prompt_for_stage', 'ensure_stage', '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
@@ -16,11 +17,63 @@ __all__ = ('prod', 'stage', 'ensure_stage',)
 # env.stages = ['prod', 'staging']
 
 
+NAMES = []
+
+def validate_stage(name):
+    "Tests whether given name is a valid staging environment."
+    name = name.strip()
+    if name not in NAMES:
+        raise Exception("%r is not a valid staging environment!" % name)
+    return name
+
+
+def prompt_for_stage(fn):
+    "Decorator which prompts for a stage-name if not set."
+    
+    @wraps(fn)
+    def wrapper(*args, **kwargs):
+        if 'deploy_env' not in env:
+            name = prompt(white('Please select a staging target %s:' % NAMES, bold=True), validate=validate_stage)
+            execute(name)
+        # Must call `execute` on the supplied task, otherwise the host-lists won't be updated.
+        execute(fn, *args, **kwargs)
+    
+    return wrapper
+
+
+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
+
+def stage(fn):
+    """ Decorator indicating this function sets a stage environment:
+        
+            @stage
+            def mystage():
+                env.deploy_env = 'mystage'
+                ...
+        
+    """
+    NAMES.append(fn.__name__)
+    __all__.append(fn.__name__)
+    return fn
+
+
+###
 # 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.
+###
 
+@stage
 def prod():
     """ Set deploy environment to production.
     """
@@ -31,23 +84,38 @@ def prod():
     env.owner      = 'www-data'
     env.group      = 'www'
 
-def stage():
-    """ Set deploy environment to stage.
+@stage
+def test():
+    """ Set deploy environment to test.
+    """
+    env.deploy_env = 'test'
+    env.hosts      = ['kripke.pmtpa.wmflabs']
+    env.gateway    = 'bastion.wmflabs.org'
+    env.target_dir = '/srv/test-reportcard.wmflabs.org/kraken-ui'
+    env.owner      = 'www-data'
+    env.group      = 'www'
+    env.supervisor_job = 'test-reportcard'
+
+@stage
+def dev():
+    """ Set deploy environment to dev.
+    """
+    env.deploy_env = 'dev'
+    env.hosts      = ['kripke.pmtpa.wmflabs']
+    env.gateway    = 'bastion.wmflabs.org'
+    env.target_dir = '/srv/dev-reportcard.wmflabs.org/kraken-ui'
+    env.owner      = 'www-data'
+    env.group      = 'www'
+    env.supervisor_job = 'dev-reportcard'
+
+@stage
+def lessly():
+    """ Set deploy environment to lessly.
     """
-    env.deploy_env = 'stage'
+    env.deploy_env = 'lessly'
     env.hosts      = ['less.ly']
     env.target_dir = '/home/wmf/projects/kraken-ui'
     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
+    del env['gateway']