Source

django-fab-deploy / fab_deploy / mysql.py

The default branch has multiple heads

Full commit
from __future__ import with_statement
from datetime import datetime
from fabric.api import *
from fabric.operations import _handle_failure
from fab_deploy import utils
from fab_deploy import system


__all__ = ['mysql_execute', 'mysql_install', 'mysql_create_db', 'mysql_create_user', 'mysqldump']


MYSQL_CREATE_USER = """CREATE USER '{db_user}'@'localhost' IDENTIFIED BY '{db_password}';"""

MYSQL_CREATE_DB = """CREATE DATABASE {db_name};"""

MYSQL_GRANT_PERMISSIONS = """
GRANT ALL ON {db_name}.* TO '{db_user}'@'localhost';
FLUSH PRIVILEGES;
"""


def _get_root_password():
    """Ask root password only once if needed"""
    if env.conf.DB_ROOT_PASSWORD is None:
        env.conf.DB_ROOT_PASSWORD = prompt('Please enter MySQL root password:')
    return env.conf.DB_ROOT_PASSWORD


@utils.run_as_sudo
def mysql_install():
    """ Installs mysql. """
    if _mysql_is_installed():
        puts('Mysql is already installed.')
        return

    passwd = _get_root_password()

    # this way mysql won't ask for a password on installation
    # see http://serverfault.com/questions/19367/scripted-install-of-mysql-on-ubuntu
    os = utils.detect_os()
    system.aptitude_install('debconf-utils')

    mysql_versions = {'lenny': '5.0', 'squeeze': '5.1', 'maverick': '5.1'}
    version = mysql_versions[os]

    debconf_defaults = [
        "mysql-server-%s mysql-server/root_password_again password %s" % (version, passwd),
        "mysql-server-%s mysql-server/root_password password %s" % (version, passwd),
    ]

    sudo("echo '%s' | debconf-set-selections" % "\n".join(debconf_defaults))

    warn('\n=========\nThe password for mysql "root" user will be set to "%s"\n=========\n' % passwd)
    system.aptitude_install('mysql-server')

def _mysql_is_installed():
    with settings(warn_only=True):
        output = run('mysql --version')
    return output.succeeded

@utils.inside_project
def mysqldump(dir=None, db_name=None, db_user=None, db_password=None):
    """ Runs mysqldump. Result is stored at <env>/var/backups/ """
    if dir is None:
        dir = env.conf.ENV_DIR + '/var/backups'
        run('mkdir -p ' + dir)
    if db_name is None:
        db_name = env.conf.DB_NAME
    if db_user is None:
        db_user = env.conf.DB_USER
    if db_password is None:
        db_password = env.conf.DB_PASSWORD

    now = datetime.now().strftime('%Y.%m.%d-%H.%M')
    run('mysqldump --user="%s" --password="%s" %s > %s/%s%s.sql' % (db_user, db_password,
                                                                    db_name, dir, db_name, now))

def mysql_execute(sql, user=None, password=None):
    """ Executes passed sql command using mysql shell. """
    user = user or env.conf.DB_USER
    if user == 'root' and password is None:
        password = _get_root_password()
    elif password is None:
        password = env.conf.DB_PASSWORD

    sql = sql.replace('"', r'\"')
    return run('echo "%s" | mysql --user="%s" --password="%s"' % (sql, user , password))

def mysql_create_user(db_user=None, db_password=None):
    if db_user is None:
        db_user = env.conf.DB_USER
        if db_user == 'root':
            _handle_failure('MySQL root user can not be created')
            return
    if db_password is None:
        db_password = env.conf.DB_PASSWORD

    sql = MYSQL_CREATE_USER.format(db_user=db_user, db_password=db_password)
    mysql_execute(sql, 'root')

def mysql_create_db(db_name=None, db_user=None):
    """ Creates an empty mysql database. """
    if db_name is None:
        db_name = env.conf.DB_NAME
    if db_user is None:
        db_user = env.conf.DB_USER

    sql = MYSQL_CREATE_DB.format(db_name=db_name, db_user=db_user)
    mysql_execute(sql, 'root')

    if db_user != 'root':
        mysql_grant_permissions(db_name=db_name, db_user=db_user)

def mysql_grant_permissions(db_name=None, db_user=None):
    if db_name is None:
        db_name = env.conf.DB_NAME
    if db_user is None:
        db_user = env.conf.DB_USER

    sql = MYSQL_GRANT_PERMISSIONS.format(db_name=db_name, db_user=db_user)
    mysql_execute(sql, 'root')