from fabric.api import env, task # # from jinja2 import Environment import os # from utils import upload_template as utils_upload_template # from utils import loggify, print_console import utils from getpass import getpass from fabric.operations import run NOTE = """ \n\n\n NOTE: you MUST deactivate the gunicorn or supervisor service if you want to make changes to the database, otherwise, the changes will not run and you will NOT BE ABLE TO SYNC. SO TURN THE FUCKING THING OFF\n\n\n""" def generate_sql(script_name): """ generates the sql files and puts them in the build directory for this branch """ configuration = env.config if env.debug: logger = utils.loggify('database', 'generate_sql') build_file = getattr(configuration.templates.database, script_name).dst build_path = os.path.join( configuration.templates.database.path.remote, 'build', build_file) template_file = getattr(configuration.templates.database, script_name).src template_dir = os.path.join( configuration.templates.database.path.local, 'files') context = dict() context['db_name'] = configuration.server.database.name context['db_user'] = configuration.server.database.user context['db_password'] = configuration.server.database.password if env.debug: logger.debug("context = %s" % context) logger.debug("build_path = %s" % build_path) logger.debug( "db_name : %s " % configuration.server.database.name) logger.debug( "db_user : %s " % configuration.server.database.user) logger.debug( "db_password : %s " % configuration.server.database.password) # # when we set debug=True, this function returns a string with the # command as it would have been executed upload_msg = utils.upload_template( filename=template_file, destination=build_path, context=context, use_jinja=True, use_sudo=False, backup=False, template_dir=template_dir, debug=True) logger.debug(upload_msg) else: utils.upload_template( filename=template_file, destination=build_path, context=context, use_jinja=True, use_sudo=False, backup=False, template_dir=template_dir) # with open(build_path, "w") as output: # output.write(rendered) print NOTE def execute_sql(script_name, add_dbname=True, is_admin=False): if env.debug: logger = utils.loggify('database', 'execute_sql') configuration = env.config build_file = getattr(configuration.templates.database, script_name).dst build_path = os.path.join( configuration.templates.database.path.remote, 'build', build_file) if add_dbname is True: db_name = configuration.server.database.name else: db_name = "postgres" port = configuration.server.database.port host = configuration.server.database.host if is_admin: user = configuration.server.database.admin.user else: user = configuration.server.database.user psql_command = "psql -h {host} -p {port} -U {user} " \ " -f {sqlfile} {db_name}".format( db_name=db_name, host=host, port=port, user=user, sqlfile=build_path,) if env.debug: logger.debug("db_name = %s" % db_name) logger.debug("run( %s ) " % psql_command) else: run_database_command(psql_command) print NOTE @task def generate(): """ helper function to upload all the scripts """ generate_sql('init') generate_sql('re_init') generate_sql('drop_db') generate_sql('drop_all') @task def clear_scripts(): """ clears all the sql scripts from scripts/conf/postgres/build/*.sql does this on the remote branch and not local. Because conf files for each branch are specifically tied to the remote site. the "local" directory refers to my computer, technically from wherever fabric is being run, but that is always development. """ configuration = env.config _template = getattr(configuration.templates, 'database') if env.debug: cmd_lsdir = "ls %s" % \ os.path.join(_template.path.remote, 'build', '*.sql') utils.printvar('cmd_lsdir', cmd_lsdir) output = run(cmd_lsdir) outputlist = output.split('\r\n') for line in outputlist: print line else: cmd_rmfiles = "rm %s" % \ os.path.join(_template.path.remote, 'build', '*.sql') output = run(cmd_rmfiles) print output @task def init(): """ runs the database intialization script """ # when initializing the database, you do NOT want # to specify which database we are connecting to, because # that database is what we are creating (we havent made it yet) execute_sql('init', add_dbname=False, is_admin=True) @task def re_init(): """ re-initializes the database drop the database, recreate it, don't touch the original user """ execute_sql('re_init', add_dbname=False, is_admin=True) @task def drop_all(): """ drop the database and drop the user """ execute_sql('drop_all', add_dbname=False, is_admin=True) @task def drop_db(): """ drop only the database but ignore the user """ execute_sql('drop_db') @task def commandline(dbuser='default'): """ logs into command line of the postgres database of the branch dbuser - set to "default" but can also be set to "admin" the admin user is what it says, I have both of these in case I need to switch between the master user for the entire postgres install or the owner of the particular database """ configuration = env.config if env.debug: logger = utils.loggify('database', 'commandline') db_name = configuration.server.database.name host = configuration.server.database.host port = configuration.server.database.port if dbuser == 'admin': user = configuration.server.database.admin.user elif dbuser == 'default': user = configuration.server.database.user if env.debug: logger.debug("branch: %s" % configuration.project.branch) logger.debug("host : %s" % host) logger.debug("port : %s" % port) logger.debug("user : %s" % user) logger.debug("name : %s" % db_name) run_database_command("psql -h {host} -p {port} -U {user} {db_name}".format( db_name=db_name, host=host, port=port, user=user )) @task def datadump(dbuser='default'): """ creates a dump of the database for backup and storage dbuser - set to "default" but can also be set to "admin" the admin user is what it says, I have both of these in case I need to switch between the master user for the entire postgres install or the owner of the particular database """ configuration = env.config db_name = configuration.server.database.name port = configuration.server.database.port host = configuration.server.database.host if dbuser == 'admin': user = configuration.server.database.admin.user elif dbuser == 'default': user = configuration.server.database.user utils.print_console("dbuser = %s" % dbuser) dumpfilename = os.path.join( configuration.paths.server.backups.database, "test.sql") cmd_pg_dump = "pg_dump -h {host} -p {port} -U {user} {db_name} " \ "-f {dumpfilename}".format( db_name=db_name, host=host, port=port, user=user, dumpfilename=dumpfilename ) run_database_command(cmd_pg_dump) # utils.print_console("cmd_pg_dump : %s" % cmd_pg_dump) def run_database_command(cmd_string): psqlpass = getpass('Enter your database password:') cmd_full = "PGPASSWORD={psqlpass} {cmd_string}".format( psqlpass=psqlpass, cmd_string=cmd_string, ) run(cmd_full) def get_template_path(script_name, script_type): configuration = env.config if script_type == 'build': file_build = getattr(configuration.templates.database, script_name).dst path = os.path.join( configuration.templates.database.path.remote, 'build', file_build) elif script_type == 'template': file_template = getattr( configuration.templates.database, script_name).src path = os.path.join( configuration.templates.database.path.remote, 'files', file_template) else: print "Error, you passed the variable %s, must pass" \ "either 'build' or 'template'" % script_type import sys sys.exit() return path @task def edit(param='help'): """ calls up mvim on the built conf files """ from maintenance import edit as maintenance_edit locations = { 'build.init': { 'path': get_template_path('init', 'build'), 'desc': 'remote init conf file', }, 'template.init': { 'path': get_template_path('init', 'template'), 'desc': 'remote version of init conf template', }, 'build.re_init': { 'path': get_template_path('re_init', 'build'), 'desc': 'remote re_init conf file', }, 'template.re_init': { 'path': get_template_path('re_init', 'template'), 'desc': 'remote version of re_init conf template', }, 'build.drop_db': { 'path': get_template_path('drop_db', 'build'), 'desc': 'remote drop_db conf file', }, 'template.drop_db': { 'path': get_template_path('drop_db', 'template'), 'desc': 'remote version of drop_db conf template', }, 'build.drop_all': { 'path': get_template_path('drop_all', 'build'), 'desc': 'remote drop_all conf file', }, 'template.drop_all': { 'path': get_template_path('drop_all', 'template'), 'desc': 'remote version of drop_all conf template', }, } if param in locations.keys(): remote_path = locations[param]['path'] maintenance_edit(remote_path=remote_path) else: print """ "fab database.edit" automates editing files important to django whether locally or remotely 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 @task def test(): configuration = env.config db_name = configuration.server.database.name host = configuration.server.database.host port = configuration.server.database.port user = configuration.server.database.user cmd_string = "psql -h {host} -p {port} -U {user} {db_name}".format( db_name=db_name, host=host, port=port, user=user ) run_database_command(cmd_string)