One way to define the server configuration by role in fabric is to define a task that specifies a host list in ʻenv.roledefs`.
environments.py
@task
def env_test():
u'''Test settings'''
env.roledefs = {
"web": ["www.test"],
"db" : ["db.test"]
}
@task
def env_production():
u'''Production settings'''
env.roledefs = {
"web": ["www01","www02"],
"db" : ["db01"]
}
However, it is a bit redundant, so I tried to generate it automatically from YAML.
env.yaml
test:
roledefs:
web: [www.test]
db: [db.test]
production:
roledefs:
web: [www01, www02]
db: [db01]
Define a helper that reads data and creates tasks like this. (Reference: http://www.backlog.jp/blog/2013/09/fabric-advanced.html)
helper/yaml_loader.py
# -*- coding: utf-8 -*-
import os, time
import yaml
from fabric.api import env,task
def load_env_from_yaml(yaml_file, namespace):
u'''Create an execution environment task from a yaml file'''
if os.path.exists(yaml_file):
env_data = yaml.safe_load(open(yaml_file).read())
for env_name, env_dict in env_data.items():
__create_env_task(env_name, env_dict, namespace)
else:
print('No {0} found. skipped.'.format(yaml_file))
def __create_env_task(env_name, env_dict, namespace):
u'''Execution environment task definition'''
f = lambda: env.update(env_dict)
f.__doc__ = u'''Set environment for {0}'''.format(env_name)
task_name = 'env_{0}'.format(env_name)
wrapper = task(name=task_name)
rand = '%d' % (time.time() * 100000)
namespace['task_%s_%s' % (task_name, rand)] = wrapper(f)
Read and use with fabfile.py.
fabfile.py
import os
from helper.yaml_loader import load_env_from_yaml
# Execute fabric at fabfile.py directory.
__fabric_dir = os.path.abspath(os.path.dirname(__file__))
os.chdir(__fabric_dir)
# Load Environments
load_env_from_yaml('env.yaml', globals())
Note that the task cannot be used unless globals ()
is passed from the fabfile.
TODO
--Exception handling --Allow task_name and task_description to be defined for readability. ――Is there a key that should not be used in ʻenv`? (However, it can be written by the above method)
Recommended Posts