from fabric.api import env, task, lcd from fabric.api import local import os import sys import utils from utils import executize, virtualenv, loggify def command(program=None, cmd=None, extra_param=None): """ takes an argument and executes that command for nginx program - name of program to be run, eg. 'nginx', 'supervisor' cmd - can be 'start', 'stop' or 'status' will then run the appropriate series of commands to get the job done based on what we have in the configuration file """ configuration = env.config # logger = loggify('maintenance', 'command') if program is None: print "Error: You have not given a legitimate program" print "permissable programs : %s" \ % configuration.maintenance.keys() sys.exit() configuration_program = getattr(configuration.maintenance, program) if cmd is None: print "Error: You have not given a legitimate command" print "permissable commands : %s" \ % configuration_program.commands.keys() sys.exit() # find out whether we are using sudo, run or local to # execute the nginx command _execute = executize(configuration_program.execute) _command = getattr(configuration_program.commands, cmd) if extra_param is not None: _command = "{command} {param}".format( command=_command, param=extra_param) if env.debug: # logger.debug( # "execute type : %s" % configuration_program.execute) # logger.debug( # "%s command : %s" % (program, _command)) # logger.debug("extra_param : %s" % extra_param) # logger.debug("%s modified command : %s" % (program, _command)) pass else: _execute(_command) def edit(remote_path, host_string=None): """ calls up mvim or vim on the file remote_path - path to file we want to edit host_string - what machine the file is located on host_string is necessary b/c in the case where I want to edit configuration files, it is essential to do so only on the localhost that is, whether I'm editing staging, development or production project yml files, the place to do that editing is ALWAYS on localhost, this is because all fabric commands are executed from localhost and will check for the necessary configuration files on local (I'm not running fabric from an ssh command line on the aws server, I'm running it on my laptop) """ logger = loggify('maintenance', 'edit') # configuration = env.config if env.debug: logger.debug("remote_path : %s" % remote_path) logger.debug("env.host_string : %s" % env.host_string) logger.debug("sys.platform : %s" % sys.platform) pass else: if sys.platform == "darwin": editor = "mvim" else: editor = "vim" if not host_string: host_string = env.host_string cmd_edit = "{editor} sftp://{user}@{host_string}/{remote_path}".format( editor=editor, user=env.user, host_string=host_string, remote_path=remote_path) local(cmd_edit) @task def pyc_delete(): """ Deletes *.pyc files from project source dir """ configuration = env.config with lcd(configuration.paths.project.root): local("find . -name '*.pyc' -delete") @task def pyc_compile(force=False): """ Compile Python source files in a project source dir """ params = [''] configuration = env.config if force: params.append('-f') with lcd(configuration.paths.project.root): with virtualenv(): local("python -m compileall {0} .".format(" ".join(params))) @task def get_base_dir(): import os BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) return BASE_DIR @task def get_project_root(): # # NOTE: the PROJECT_ROOT value is very important. Make sure that # if you move around this file, you account for where it is and add # or take away "os.pardir" from os.path.join PROJECT_ROOT = os.path.abspath( os.path.join(get_base_dir(), os.pardir, os.pardir, os.pardir)) return PROJECT_ROOT def _get_configuration_path(name, branch): # # the locations of the files we need relative to the PROJECT_ROOT param_list = ['config', 'layout'] if name not in param_list: print "value %s was not legit. _get_configuration_path requires" \ "value such from %s" % (name, param_list) META_DIR = os.path.join( get_project_root(), 'usr', 'meta', 'project') if name == "config": # # the configuration we are working with will change # depending on what branch is being used. This value # is passed in when the function is called configname = "{branch}.yml".format(branch=branch) path_meta = os.path.join(META_DIR, configname) elif name == "layout": path_meta = os.path.join(META_DIR, 'layout.yml') return path_meta def load_configuration(name, branch): import yaml # # the locations of the files we need relative to the PROJECT_ROOT if name == "fabric": file_path = os.path.join( get_project_root(), 'scripts', 'fabric', 'share', 'fabric.yml') elif name == "config": # # the configuration we are working with will change # depending on what branch is being used. This value # is passed in when the function is called file_path = _get_configuration_path('config', branch) elif name == "layout": file_path = _get_configuration_path('layout', branch) configuration_file = yaml.load(file(file_path, 'r')) return configuration_file @task def check_version(branchname): """ Maintenance function to check the configuration version against the fabric version currently loaded. Returns boolean If the version is either non-existant or not the same as the fabric configuration version, then a message will be sent to the user letting him know, and giving him the option to stop the program. If he chooses to continue, the function will return "False" to the calling function Otherwise, everything will continue as normal and "True" will be returned Keyword Arguments: branchname -- the name of the branch whose configuration files we are checking """ config = load_configuration("config", branchname) fabric_config = load_configuration("fabric", branchname) if 'version' in config: config_version = config['version'] else: config_version = 0 version_correct = config_version >= fabric_config['version'] utils.printvar('version_correct', version_correct) if not version_correct: # TODO # update this message, currently it is false because there is no # fabric.updateconfs function! version_false = """ NOTE: the current configuration information related to this project is not up to date, the fabric tools are at version %s, and you are at version %s. Run fab fabric.updateconfs to correct.\n""" utils.print_console( version_false % (fabric_config['version'], config_version), numsep=90) # utils.prompt_continue() # version was not correct return False to let the app # know what's going on return False # version was correct, so return True to let the app know # everything is A-OK return True