import os import errno import logging import fabric.contrib.files from contextlib import contextmanager as _contextmanager from fabric.api import env, prefix, local from fabric.operations import run, sudo def printvar(name, value, exit=False): print "%s : %s" % (name, value) if exit: import sys sys.exit() def loggify(module, func, prefix=""): """ I'm tired of rewriting this logging code in every single function, so I decided to just dump it here, and return a logger that can be used and thrown away when it's done module - name of the module being used, ie 'nginx', 'deploy', etc func - the name of the function this logger is going to be used in prefix - anything you want to add to the front of the logger, ie '\n' returns a logging object """ loggername = '{module}.{func}'.format( module=module, func=func) str_logging = '{prefix}%(levelname)s: {loggername} %(message)s'.format( prefix=prefix, loggername=loggername) logging.basicConfig( format=str_logging, level=logging.DEBUG) return logging.getLogger(loggername) def print_console(string, prepend="\n\n", append="\n\n", sep="-", numsep=44): """ helper function to take a string, and format it so it prints to the console in a way that is pleasing to the eye. string - the string to be printed prepend - defaults to two line spaces, can be anything append - defaults to two lines spaces after the string is printed sep - the character used to print out one line above the string and one line after numsep - number of times the separator is printed out on a line """ print prepend if sep: print sep * numsep print string if sep: print sep * numsep print append def print_debug(debugstr, module, function): print "%s:%s:%s" \ % (module, function, debugstr) def executize(config_execute): """ A couple of times using fabric I've found that I'll need to switch between sudo, run or local depending on where I'm executing the function, because repeating this code in every funcion that needs it can be straingint on the eyes, I'm putting it here for use. config_execute - a string that can represent the value of 'sudo', 'run', or 'local' return the fabric command corresponding to the string value in config_execute """ _execute = local if config_execute == 'sudo': _execute = sudo elif config_execute == 'run': _execute = run elif config_execute == 'local': _execute = local return _execute def booleanize(value): """ take the argument and return it as either True or False if the argument is neither, return False by default and warn the user that there is a problem """ true_values = ("y", "yes", "true", "1") false_values = ("n", "no", "false", "0") if isinstance(value, bool): return value if value.lower() in true_values: return True elif value.lower() in false_values: return False raise TypeError("Cannot booleanize ambiguous value '%s'" % value) def ensure_dir(directory): """ Create a directory if it's not exists """ try: if not os.path.exists(directory): print "creating directory: %s" % directory os.makedirs(directory) except OSError, e: if e.errno != errno.EEXIST: print "Error occurred while creating directory: %s" % directory raise def ensure_file(f): """ Simulates linux 'touch' command """ if not os.path.exists(f): open(f, 'w').close() def upload_template(filename, destination, context, use_jinja, use_sudo, backup, template_dir, debug=False): if env.debug: logging.basicConfig( format='\n%(levelname)s: utils.upload_template %(message)s', level=logging.DEBUG) command_msg = "\n\tupload_template(" \ "\n\tfilename={filename}," \ "\n\tdestination={destination_available}," \ "\n\tcontext={context}," \ "\n\tuse_jinja={use_jinja}," \ "\n\tuse_sudo={use_sudo}," \ "\n\tbackup={backup}," \ "\n\ttemplate_dir={template_dir})\n".format( filename=filename, destination_available=destination, context=context, use_jinja=use_jinja, use_sudo=use_sudo, backup=backup, template_dir=template_dir) if debug: return command_msg else: fabric.contrib.files.upload_template( filename=filename, destination=destination, context=context, use_jinja=use_jinja, use_sudo=use_sudo, backup=backup, template_dir=template_dir) def get_upload_template_msg(filename, destination, context, use_jinja, use_sudo, backup, template_dir, debug=False): command_msg = "\n\tupload_template(" \ "\n\tfilename={filename}," \ "\n\tdestination={destination_available}," \ "\n\tcontext={context}," \ "\n\tuse_jinja={use_jinja}," \ "\n\tuse_sudo={use_sudo}," \ "\n\tbackup={backup}," \ "\n\ttemplate_dir={template_dir})\n".format( filename=filename, destination_available=destination, context=context, use_jinja=use_jinja, use_sudo=use_sudo, backup=backup, template_dir=template_dir) return command_msg @_contextmanager def virtualenv_source(): with prefix("source virtualenvwrapper.sh"): yield @_contextmanager def virtualenv(): configuration = env.config with virtualenv_source(): with prefix("workon %s" % configuration.virtualenv.name): yield # with prefix("/bin/bash -c -l 'source %s'" % # configuration.virtualenv.activate): # yield # with prefix("/bin/bash -c -l 'source /usr/local/bin/' \ # 'virtualenvwrapper.sh ' \ # '&& workon %s'" % configuration.virtualenv.name): # yield def generate_template_build_path(section, template_name='conf'): """ helper function to automate creation of build path section - the template section we are building off of template_name - by default this is "conf", but can be different, for example, the 'database' section has 3 different template names returns a path to where the template should be placed """ import os configuration = env.config conf_section = getattr(configuration.templates, section) conf_section_templatename = getattr(conf_section, template_name) build_path = os.path.join( conf_section.path.remote, 'build', conf_section_templatename.dst) return build_path def generate_template_files_path(section): """ helper function to automate creation of build path section - the template section we are building off of returns a path to where the template jinja file is located """ import os configuration = env.config conf_section = getattr(configuration.templates, section) files_path = os.path.join( conf_section.path.local, 'files') return files_path def print_run(command, prefix="\"\n\t", suffix="\n\t\""): """ helper function for when I want a string that has the form "\n\t run(some_command_string) \t\n" where "somce_command_string" is a bash script commmand or something like that """ return "run ({prefix}{command}{suffix})".format( prefix=prefix, suffix=suffix, command=command) def handle_help(param, message, values=None): values_default = ['-h', '--help'] if values is None: values = values_default if isinstance(param, str): if param.lower() in values: print message return True return False def is_help(key): help_keys = ['-h', '--help'] return key in help_keys def link_create(path_src, path_dst, debug=False): """ takes a source and destination path, then links it if the destination path already exists and is a link, then delete it. Otherwise sys.exit path_src - source path path_dst - destination path returns: if debug=True then it returns a msg """ from fabric.contrib.files import is_link from fabric.contrib.files import exists from fabric.operations import run cmd_rm = "rm {path_dst}".format( path_dst=path_dst ) cmd_link = "ln -sf {path_src} {path_dst}".format( path_src=path_src, path_dst=path_dst ) msg_debug = "" if exists(path_dst): if is_link(path_dst): if debug: msg_debug += "link already exists at dst, removing\n" \ "link_create:cmd_rm : %s" % cmd_rm else: run(cmd_rm) else: msg_error = "something exists at dst - '%s' " \ "- and it's not a link\n kicking out".format(path_dst) import sys sys.exit(msg_error) if debug: msg_debug += "link_create:cmd_link : %s" % cmd_link else: run(cmd_link) return msg_debug def prompt_continue(message="Do you want to continue? Y/n", default="Y"): """ prompts user if he wants to continue Keyword Arguments: message -- ask if user wants to continue default -- what to do if the user hits enter without giving a value """ from fabric.operations import prompt import sys prompt_val = prompt(message) if prompt_val == "": prompt_val = default if env.debug: printvar( "prompt_val", prompt_val, not booleanize(prompt_val)) else: if not booleanize(prompt_val): sys.exit() def check_debug(env): if hasattr(env, 'debug'): return env.debug else: return False