from fabric.operations import run, put from fabric.api import env, task import os from .maintenance import _get_configuration_path, load_configuration @task def deploy(param=None): param_list = ['conf', 'readmes'] if not param: print("this requires input param must be one of %s" % param_list) import sys sys.exit() if param == 'conf': deploy_conf() elif param == 'readmes': deploy_readmes() @task def backup(param=None): """ reads template files from the project and stores them options are to store: configuration files from projectname/usr/etc meta files from projectname/usr/meta readmes from projectname/share/readmes """ param_list = ['conf', 'meta', 'readmes'] if not param: print("this requires input param must be one of %s" % param_list) import sys sys.exit() if param == 'conf': _backup_conf() elif param == 'meta': _backup_meta() elif param == 'readmes': _backup_readmes() def _backup_conf(): configuration = env.config for key in configuration.templates.keys(): section = getattr(configuration.templates, key) source_path = os.path.join(section['path']['local'], 'files') dest_path = os.path.join( configuration.tools.fabric.templates.conf, key) run("mkdir -p %s" % dest_path) put(source_path, dest_path) def _backup_meta(): configuration = env.config from fabric.operations import run, put source_path_layout = _get_configuration_path( 'layout', 'development') config_dev = _modify_configuration('development') config_stg = _modify_configuration('staging') dest_path = configuration.tools.fabric.templates.meta run("mkdir -p %s" % dest_path) # # copy over the layout.yml file only put(source_path_layout, dest_path) # # the development.yml file needs to be # modified before it can be copied over _store_configuration(config_dev, 'development') _store_configuration(config_stg, 'staging') def _backup_readmes(): configuration = env.config dest_readmes = configuration.tools.fabric.templates.readmes source_readmes = os.path.join( configuration.paths.project.root, 'share', 'readmes') copy_directories(source_readmes, dest_readmes) def _modify_configuration(branch): """ this method modifies a meta/branch.yml file so that it can be stored as a template for future branch files of the same time. Keyword arguments: branch -- the name of the branch whose configuration files we are modifying Notice that some of the values requires me to store the values with certain names, e.g. if the project/host is NOT 'localhost', then override the stored IP address with the word "PROJECT_IP" this method is meant to be used by _store_configuration """ # # get the configuration dict for this branch config_yaml = load_configuration('config', branch) # # basic project configuration branch = config_yaml['project']['branch'] config_yaml['project']['name'] = 'PROJECT_NAME' # we don't use 'paths/home' in anything other than dev if branch == 'development': config_yaml['project']['paths']['home'] = 'PROJECT_NAME.prj' else: config_yaml['project']['branch'] = "BRANCH_NAME" config_yaml['project']['user'] = 'BRANCH_USER' config_yaml['project']['group'] = 'BRANCH_GROUP' config_yaml['project']['extension'] = 'BRANCH_EXT' if config_yaml['project']['host'] != 'localhost': config_yaml['project']['host'] = 'PROJECT_IP' # # database configuration config_yaml['database']['name'] = "PROJECT_NAME_{branch}".format( branch=config_yaml['project']['extension']) if config_yaml['database']['host'] == "docker": config_yaml['database']['port'] = 'DOCKER_PORT' else: config_yaml['database']['host'] = 'DATABASE_IP' # # database user name values config_yaml['database']['users']['admin']['name'] = \ 'DATABASE_ADMIN_NAME' config_yaml['database']['users']['admin']['pass'] = \ 'DATABASE_ADMIN_PASS' config_yaml['database']['users']['default']['name'] = \ 'DATABASE_USER_NAME' config_yaml['database']['users']['default']['pass'] = \ 'DATABASE_USER_PASS' # # django configuration config_yaml['django']['port'] = 'DJANGO_PORT' config_yaml['django']['host'] = 'DJANGO_IP' # # nginx and virtualenv configuration config_yaml['nginx']['port'] = 'NGINX_PORT' if 'name' in config_yaml['virtualenv']: config_yaml['virtualenv']['name'] = 'PROJECT_NAME' return config_yaml def _store_configuration(config_dict, branch): """ takes config dictionary converts it to a yaml file object, then saves it under the appropriate file name Keyword arguments: config_dict -- yaml based configuration dictionary object """ configuration = env.config from StringIO import StringIO import yaml from fabric.operations import put branch_name = branch + ".yml" dest_path = os.path.join( configuration.tools.fabric.templates.meta, branch_name) put(StringIO(yaml.dump(config_dict)), dest_path) def deploy_readmes(): """ takes the readme files from tools/fabric/templates/readmes and puts then under the top level of the project/scripts directory """ configuration = env.config source_readmes = configuration.tools.fabric.templates.readmes dest_readmes = os.path.join( configuration.paths.project.root, 'share', 'readmes') copy_directories(source_readmes, dest_readmes) def deploy_conf(): """ takes the conf templates from tools/fabric/templates/conf and puts them under scripts/conf. Note, these "conf" files are NOT the same as the meta/branch.yml conf files. They are configuration files meant for the various subsystems of the project. ie, database, docker, supervisor, etc. """ configuration = env.config for key in configuration.templates.keys(): section = getattr(configuration.templates, key) dest_path = section['path']['local'] source_path = os.path.join( configuration.tools.fabric.templates.conf, key) build_dir = os.path.join(dest_path, 'build') # also create the destination 'build' directories # if they do not exist run("mkdir -p %s" % build_dir) copy_directories(source_path, dest_path) def copy_directories(source_path, dest_path): """ takes the files from source and copies them to dest using fabric.put Keyword arguments: source_path -- the source dir dest_path -- the destination dir """ run("mkdir -p %s" % dest_path) file_list = run("ls %s" % source_path).split() for fname in file_list: fpath = os.path.join(source_path, fname) put(fpath, dest_path) @task def edit(param='help'): """ calls up mvim on the yaml project configuration files """ from .maintenance import edit as maintenance_edit from .maintenance import _get_configuration_path locations = { 'development': { 'path': _get_configuration_path("config", "development"), 'desc': 'development project configuration file', }, 'staging': { 'path': _get_configuration_path("config", "staging"), 'desc': 'staging project configuration file', }, 'production': { 'path': _get_configuration_path("config", "production"), 'desc': 'production project configuration file', }, } if param in locations.keys(): # it is unnecessary to give the host_string to edit # because the host_string is determined when we call fab # ie. "fab devel whatever" or "fab stage whatever" # we want to edit all files on localhost. b/c we only call # fab FROM localhost remote_path = locations[param]['path'] maintenance_edit(remote_path=remote_path) else: # if param == 'help': print(""" "fab configuration.edit" automates opening up and editing project configuration files to use this you must pass one of the editable locations in as a parameter currently editable locations are: """) for k_loc in locations.keys(): print("\t{0: <20} - {1}".format(k_loc, locations[k_loc]['desc'])) return