Skip to content

Instantly share code, notes, and snippets.

@bennylope
Created December 17, 2015 15:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bennylope/09bd1602d8050002d002 to your computer and use it in GitHub Desktop.
Save bennylope/09bd1602d8050002d002 to your computer and use it in GitHub Desktop.
Use Fabric to manage envdir compatible configuration data
"""
Remote environment variable configuration using envdir
This should be set up using a `fabfile/` module rather than
an individual `fabfile.py` file.
$ fab <env> config -- list environment variables (incl. values)
$ fab <env> config.set:DEBUG=False -- set a single variable
$ fab <env> config.set:DEBUG=False,SECRET=jdkjkjk -- set multiple variables
$ fab <env> config.remove:DEBUG -- remove a single variable
$ fab <env> config.remove:DEBUG,SECRET -- remove multiple variables
Requires that `env.config_dir` is set prior to running.
:author: Ben Lopatin
:license: BSD
"""
from fabric.api import task, run
from fabric.context_managers import cd, hide
from fabric.state import env
@task(default=True)
def list():
"""Lists the environment variables for the app user"""
with hide('running', 'stdout'):
with cd(env.config_dir):
environment = {
var: run("cat {}".format(var))
for var in run("ls").split()
}
longest_key = max([len(i) for i in environment.keys()]) + 1
padding = 30 if longest_key < 30 else longest_key
print_str = "{{:<{}}} {{}}".format(padding)
# Why not use an OrderedDict?? Because an OrderedDict only orders based on
# the input, and the input even from `ls` was oddly not sorted
# alphabetically.
for var in sorted(environment.keys()):
print print_str.format(var, environment[var])
@task
def set(**kwargs):
"""Add one or more shell variables to the app environment"""
with hide('running', 'stdout'):
with cd(env.config_dir):
for var, value in kwargs.items():
run("echo '{0}' > {1}".format(value, var))
@task
def remove(*args):
"""Remove configuration variables from the app environment"""
with hide('running', 'stdout'):
with cd(env.config_dir):
envvars = [var for var in run("ls").split()]
for env_key in args:
if env_key not in envvars:
print("No such variable {0}".format(env_key))
continue
run("rm {0}".format(env_key))
@bennylope
Copy link
Author

Application restart is a second distinct step. Would ideally be added via a decorator, optionally naming services to be restarted.

@task
@restart_services('gunicorn', 'celery')
def set(**kwargs):
    """Add one or more shell variables to the app environment"""
    with hide('running', 'stdout'):
        with cd(env.config_dir):
            for var, value in kwargs.items():
                run("echo '{0}' > {1}".format(value, var))
    return True  # Use a boolean to flag restarting or not

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment