#!/bin/bash
#
# lib/databases/mysql
# Functions to control the configuration and operation of the **MySQL** database backend

# Dependencies:
#
# - DATABASE_{HOST,USER,PASSWORD} must be defined

# Save trace setting
_XTRACE_DB_MYSQL=$(set +o | grep xtrace)
set +o xtrace

MYSQL_DRIVER=${MYSQL_DRIVER:-PyMySQL}

register_database mysql

MYSQL_SERVICE_NAME=mysql
if is_fedora && ! is_oraclelinux; then
    MYSQL_SERVICE_NAME=mariadb
elif is_suse && systemctl list-unit-files | grep -q 'mariadb\.service'; then
    # Older mariadb packages on SLES 12 provided mysql.service.  The
    # newer ones on SLES 12 and 15 use mariadb.service; they also
    # provide a mysql.service symlink for backwards-compatibility, but
    # let's not rely on that.
    MYSQL_SERVICE_NAME=mariadb
fi

# Functions
# ---------

function get_database_type_mysql {
    if [[ "$MYSQL_DRIVER" == "PyMySQL" ]]; then
        echo mysql+pymysql
    else
        echo mysql
    fi
}

# Get rid of everything enough to cleanly change database backends
function cleanup_database_mysql {
    stop_service $MYSQL_SERVICE_NAME
    if is_ubuntu; then
        # Get ruthless with mysql
        apt_get purge -y mysql* mariadb*
        sudo rm -rf /var/lib/mysql
        sudo rm -rf /etc/mysql
        return
    elif is_oraclelinux; then
        uninstall_package mysql-community-server
        sudo rm -rf /var/lib/mysql
    elif is_suse || is_fedora; then
        uninstall_package mariadb-server
        sudo rm -rf /var/lib/mysql
    else
        return
    fi
}

function recreate_database_mysql {
    local db=$1
    mysql -u$DATABASE_USER -p$DATABASE_PASSWORD -h$MYSQL_HOST -e "DROP DATABASE IF EXISTS $db;"
    mysql -u$DATABASE_USER -p$DATABASE_PASSWORD -h$MYSQL_HOST -e "CREATE DATABASE $db CHARACTER SET utf8;"
}

function configure_database_mysql {
    local my_conf mysql slow_log
    echo_summary "Configuring and starting MySQL"

    if is_ubuntu; then
        my_conf=/etc/mysql/my.cnf
    elif is_suse || is_oraclelinux; then
        my_conf=/etc/my.cnf
    elif is_fedora; then
        my_conf=/etc/my.cnf
        local cracklib_conf=/etc/my.cnf.d/cracklib_password_check.cnf
        if [ -f "$cracklib_conf" ]; then
            inicomment -sudo "$cracklib_conf" "mariadb" "plugin-load-add"
        fi
    else
        exit_distro_not_supported "mysql configuration"
    fi

    # Start mysql-server
    if is_fedora || is_suse; then
        # service is not started by default
        start_service $MYSQL_SERVICE_NAME
    fi

    # Set the root password - only works the first time. For Ubuntu, we already
    # did that with debconf before installing the package, but we still try,
    # because the package might have been installed already.
    sudo mysqladmin -u root password $DATABASE_PASSWORD || true

    # Update the DB to give user '$DATABASE_USER'@'%' full control of the all databases:
    sudo mysql -uroot -p$DATABASE_PASSWORD -h127.0.0.1 -e "GRANT ALL PRIVILEGES ON *.* TO '$DATABASE_USER'@'%' identified by '$DATABASE_PASSWORD';"

    # Now update ``my.cnf`` for some local needs and restart the mysql service

    # Change bind-address from localhost (127.0.0.1) to any (::) and
    # set default db type to InnoDB
    iniset -sudo $my_conf mysqld bind-address "$(ipv6_unquote $SERVICE_LISTEN_ADDRESS)"
    iniset -sudo $my_conf mysqld sql_mode TRADITIONAL
    iniset -sudo $my_conf mysqld default-storage-engine InnoDB
    iniset -sudo $my_conf mysqld max_connections 1024
    iniset -sudo $my_conf mysqld query_cache_type OFF
    iniset -sudo $my_conf mysqld query_cache_size 0

    if [[ "$DATABASE_QUERY_LOGGING" == "True" ]]; then
        echo_summary "Enabling MySQL query logging"
        if is_fedora; then
            slow_log=/var/log/mariadb/mariadb-slow.log
        else
            slow_log=/var/log/mysql/mysql-slow.log
        fi
        sudo sed -e '/log.slow.queries/d' \
            -e '/long.query.time/d' \
            -e '/log.queries.not.using.indexes/d' \
            -i $my_conf

        # Turn on slow query log, log all queries (any query taking longer than
        # 0 seconds) and log all non-indexed queries
        iniset -sudo $my_conf mysqld slow-query-log 1
        iniset -sudo $my_conf mysqld slow-query-log-file $slow_log
        iniset -sudo $my_conf mysqld long-query-time 0
        iniset -sudo $my_conf mysqld log-queries-not-using-indexes 1
    fi

    restart_service $MYSQL_SERVICE_NAME
}

function install_database_mysql {
    if is_ubuntu; then
        # Seed configuration with mysql password so that apt-get install doesn't
        # prompt us for a password upon install.
        sudo debconf-set-selections <<MYSQL_PRESEED
mysql-server mysql-server/root_password password $DATABASE_PASSWORD
mysql-server mysql-server/root_password_again password $DATABASE_PASSWORD
mysql-server mysql-server/start_on_boot boolean true
MYSQL_PRESEED
    fi

    # while ``.my.cnf`` is not needed for OpenStack to function, it is useful
    # as it allows you to access the mysql databases via ``mysql nova`` instead
    # of having to specify the username/password each time.
    if [[ ! -e $HOME/.my.cnf ]]; then
        cat <<EOF >$HOME/.my.cnf
[client]
user=$DATABASE_USER
password=$DATABASE_PASSWORD
host=$MYSQL_HOST
EOF
        chmod 0600 $HOME/.my.cnf
    fi
    # Install mysql-server
    if is_oraclelinux; then
        install_package mysql-community-server
    elif is_fedora || is_suse; then
        install_package mariadb-server
        sudo systemctl enable $MYSQL_SERVICE_NAME
    elif is_ubuntu; then
        install_package mysql-server
    else
        exit_distro_not_supported "mysql installation"
    fi
}

function install_database_python_mysql {
    # Install Python client module
    pip_install_gr $MYSQL_DRIVER
    if [[ "$MYSQL_DRIVER" == "MySQL-python" ]]; then
        ADDITIONAL_VENV_PACKAGES+=",MySQL-python"
    elif [[ "$MYSQL_DRIVER" == "PyMySQL" ]]; then
        ADDITIONAL_VENV_PACKAGES+=",PyMySQL"
    fi
}

function database_connection_url_mysql {
    local db=$1
    echo "$BASE_SQL_CONN/$db?charset=utf8"
}


# Restore xtrace
$_XTRACE_DB_MYSQL

# Local variables:
# mode: shell-script
# End:
