#!/bin/bash # # $Id$ # # SER MySQL Database Administration Tool # # Copyright (C) 2006-2008 iptelorg GmbH # ################################################################# # configuration variables ################################################################# DEFAULT_DBHOST="localhost" # Default hostname of the database server DEFAULT_SQLUSER="root" # Database username with admin privileges DEFAULT_DBNAME="ser" # Default name of SER database DEFAULT_ROUSER="serro" # Default read-only username to SER database DEFAULT_ROPASS="47serro11" # Default password of read-only user DEFAULT_RWUSER="ser" # Default username of read-write user DEFAULT_RWPASS="heslo" # Default password of read-write user DEFAULT_MYSQL="mysql" DEFAULT_MYSQLDUMP="mysqldump" # The default directory which contains SQL scripts. If empty then the # directory which contains this shell script will be used. If relative then # the pathname will be made absolute with respect to the location of this # shell script. DEFAULT_SCRIPT_DIR="" DEFAULT_CREATE_SCRIPT="my_create.sql" DEFAULT_DATA_SCRIPT="my_data.sql" DEFAULT_DROP_SCRIPT="my_drop.sql" CMD="$MYSQL -f -h$DBHOST -u$SQLUSER" DEFAULT_DUMP_OPTS="-c -a -e --add-locks --all" usage() { cat < Backup the contents of SER database. If you specify a filename then the contents of the database will be saved in that file, otherwise the tool will dumps the contents to the standard output. By default the backup SQL data contains CREATE TABLE statements that will drop and recreate database tables being loaded. This ensures that the tables are empty and have correct structure. You can change this behavior using -t command line option. restore Load the contents of SER database from a file (if you specify one) or from the standard input. Make sure that the database exists before you load the data. Make sure that the database is empty if you have backups without create table statements (i.e. created with -t command line option) and that the tables are empty. update-data Update initial data in the database. This command deletes vendor-controlled rows from the database and replaces them with new data. OPTIONS -h, --help Display this help text. -n NAME, --name=NAME Database name of SER database. (Default value is '$DEFAULT_DBNAME') -r USERNAME, --ro-username=USERNAME Username of user with read-only permissions to SER database. (Default value is '$DEFAULT_ROUSER') -w USERNAME, --rw-username=USERNAME Username of user with read-write permissions to SER database. (Default value is '$DEFAULT_RWUSER') -p PASSWORD, --ro-password=PASSWORD Password of user with read-only permissions to SER database. (Default value is '$DEFAULT_ROPASS') -P PASSWORD, --rw-password=PASSWORD Password of user with read-write permissions to SER database. (Default value is '$DEFAULT_RWPASS') -t, --tables Do not write CREATE TABLE statements that recreate tables when restoring data from backup. -s HOST, --server=HOST Hostname or IP address of database server. (Default value is '$DEFAULT_DBHOST') -u USERNAME, --username=USERNAME Username of database administrator. (Default value is '$DEFAULT_SQLUSER') -q[PASSWORD], --sql-password[=PASSWORD] Database administrator password. If you specify this option without value then the script will assume that no password for database administrator is needed and will not ask for it. (No default value) -d DIRECTORY, --script-dir=DIRECTORY Directory containing the SQL scripts with database schema and initial data definition. (Default value is '$DEFAULT_SCRIPT_DIR') -k, --keep-users Do not delete database users when removing the database. This is useful if you have multiple databases and use the same users to access them. -v, --verbose Enable verbose mode. This option can be given multiple times to produce more and more output. ENVIRONMENT VARIABLES MYSQL Path to mysql command (Currently ${MYSQL}) MYSQLDUMP Path to mysqldump command (Currently ${MYSQLDUMP}) AUTHOR Written by Jan Janak COPYRIGHT Copyright (C) 2006-2008 iptelorg GmbH This is free software. You may redistribute copies of it under the termp of the GNU General Public License. There is NO WARRANTY, to the extent permitted by law. FILES ${SCRIPT_DIR}/${CREATE_SCRIPT} ${SCRIPT_DIR}/${DATA_SCRIPT} ${SCRIPT_DIR}/${DROP_SCRIPT} REPORTING BUGS Report bugs to EOF } #usage # Read password from user prompt_pw() { export PW if [ ! -z $DONT_ASK ] ; then unset PW return 0 elif [ -z "$PW" ] ; then savetty=`stty -g` printf "Enter password for MySQL user ${SQLUSER} (Hit enter for no password): " stty -echo read PW stty $savetty echo fi if [ -z "$PW" ]; then unset PW else PW="-p$PW" fi } # Convert relative path to the script directory to absolute if necessary by # extracting the directory of this script and prefixing the relative path with # it. abs_script_dir() { my_dir=`dirname $0`; if [ "${SCRIPT_DIR:0:1}" != "/" ] ; then SCRIPT_DIR="${my_dir}/${SCRIPT_DIR}" fi } # Execute an SQL command sql_query() { if [ $# -gt 1 ] ; then if [ -n "$1" ]; then DB=\"$1\" else DB="" fi shift if [ -n "$PW" ]; then $CMD "$PW" $MYSQL_OPTS $DB -e "$@" else $CMD $MYSQL_OPTS $DB -e "$@" fi else if [ -n "$PW" ]; then $CMD "$PW" $MYSQL_OPTS "$@" else $CMD $MYSQL_OPTS "$@" fi fi } # Drop SER database drop_db() { # Drop the database if it exists sql_query "" "DROP DATABASE IF EXISTS ${DBNAME}" # Revoke permissions to both RW and RO users sql_query "" "REVOKE ALL PRIVILEGES ON ${DBNAME}.* FROM '${RWUSER}'@'%'" sql_query "" "REVOKE ALL PRIVILEGES ON ${DBNAME}.* FROM '${RWUSER}'@'localhost'" sql_query "" "REVOKE ALL PRIVILEGES ON ${DBNAME}.* FROM '${ROUSER}'@'%'" sql_query "" "REVOKE ALL PRIVILEGES ON ${DBNAME}.* FROM '${ROUSER}'@'localhost'" if [ ! -z "$KEEP_USERS" ] ; then # Works only with MySQL 4.1.1 and higher #sql_query "" "DROP USER '${RWUSER}'@'%'" #sql_query "" "DROP USER '${RWUSER}'@'localhost'" #sql_query "" "DROP USER '${ROUSER}'@'%'" #sql_query "" "DROP USER '${ROUSER}'@'localhost'" # Works with older MySQL versions sql_query "" "DELETE FROM mysql.user WHERE User='${RWUSER}' and Host='%'" sql_query "" "DELETE FROM mysql.user WHERE User='${RWUSER}' and Host='localhost'" sql_query "" "DELETE FROM mysql.user WHERE User='${ROUSER}' and Host='%'" sql_query "" "DELETE FROM mysql.user WHERE User='${ROUSER}' and Host='localhost'" fi sql_query "" "FLUSH PRIVILEGES" } # drop_db # Create SER database create_db () { # Create the database sql_query "" "CREATE DATABASE IF NOT EXISTS ${DBNAME}" # Add read/write access to RWUSER sql_query "" "GRANT ALL ON ${DBNAME}.* TO '${RWUSER}'@'%' IDENTIFIED BY '${RWPASS}'" sql_query "" "GRANT ALL ON ${DBNAME}.* TO '${RWUSER}'@'localhost' IDENTIFIED BY '${RWPASS}'" # Add read-only access to ROUSER sql_query "" "GRANT ALL ON ${DBNAME}.* TO '${ROUSER}'@'%' IDENTIFIED BY '${ROPASS}'" sql_query "" "GRANT ALL ON ${DBNAME}.* TO '${ROUSER}'@'localhost' IDENTIFIED BY '${ROPASS}'" # Activate changes sql_query "" "FLUSH PRIVILEGES" # Load table definitions sql_query $DBNAME < ${SCRIPT_DIR}/${CREATE_SCRIPT} # Load initial data sql_query $DBNAME < ${SCRIPT_DIR}/${DATA_SCRIPT} } # create_db # Update initial data update_db_data () { sql_query $DBNAME < ${SCRIPT_DIR}/${DATA_SCRIPT} } # update_db_data # Main program COMMAND=`basename $0` if [ -z "$DBNAME" ] ; then DBNAME="$DEFAULT_DBNAME"; fi; if [ -z "$ROUSER" ] ; then ROUSER="$DEFAULT_ROUSER"; fi; if [ -z "$RWUSER" ] ; then RWUSER="$DEFAULT_RWUSER"; fi; if [ -z "$ROPASS" ] ; then ROPASS="$DEFAULT_ROPASS"; fi; if [ -z "$RWPASS" ] ; then RWPASS="$DEFAULT_RWPASS"; fi; if [ -z "$DBHOST" ] ; then DBHOST="$DEFAULT_DBHOST"; fi; if [ -z "$SQLUSER" ] ; then SQLUSER="$DEFAULT_SQLUSER"; fi; if [ -z "$MYSQL" ] ; then MYSQL="$DEFAULT_MYSQL"; fi if [ -z "$MYSQLDUMP" ] ; then MYSQLDUMP="$DEFAULT_MYSQLDUMP"; fi if [ -z "$DUMP_OPTS" ] ; then DUMP_OPTS="$DEFAULT_DUMP_OPTS"; fi if [ -z "$SCRIPT_DIR" ] ; then SCRIPT_DIR="$DEFAULT_SCRIPT_DIR"; fi if [ -z "$CREATE_SCRIPT" ] ; then CREATE_SCRIPT="$DEFAULT_CREATE_SCRIPT"; fi if [ -z "$DATA_SCRIPT" ] ; then DATA_SCRIPT="$DEFAULT_DATA_SCRIPT"; fi if [ -z "$DROP_SCRIPT" ] ; then DROP_SCRIPT="$DEFAULT_DROP_SCRIPT"; fi # Make the path to the script directory absolute abs_script_dir TEMP=`getopt -o hn:r:w:p:P:ts:u:vkq::d: --long help,name:,ro-username:,rw-username:,\ ro-password:,rw-password:,tables,server:,username:,verbose,keep-users],\ sql-password::,script-dir: -n $COMMAND -- "$@"` if [ $? != 0 ] ; then exit 1; fi eval set -- "$TEMP" while true ; do case "$1" in -h|--help) usage; exit 0 ;; -n|--name) DBNAME=$2; shift 2 ;; -r|--ro-username) ROUSER=$2; shift 2 ;; -w|--rw-username) RWUSER=$2; shift 2 ;; -p|--ro-password) ROPASS=$2; shift 2 ;; -P|--rw-password) RWPASS=$2; shift 2 ;; -t|--tables) DUMP_OPTS="$DUMP_OPTS -t "; shift ;; -s|--server) DBHOST=$2; shift 2 ;; -u|--username) SQLUSER=$2; shift 2 ;; -v|--verbose) MYSQL_OPTS="$MYSQL_OPTS -v "; shift ;; -k|--keep-users) KEEP_USERS=1; shift ;; -d|--script-dir) SCRIPT_DIR=$2; # The script directory changed, make it absolute again abs_script_dir shift 2 ;; -q|--sql-password) case "$2" in "") DONT_ASK=1; shift 2 ;; *) PW=$2; shift 2 ;; esac ;; --) shift; break ;; *) echo "Internal error"; exit 1 ;; esac done if [ $# -eq 0 ]; then usage exit 1 fi # Make sure we can execute mysql command TEMP=`which $MYSQL` if [ $? != 0 ] ; then echo "Could not find mysql client utility" echo "Set MYSQL environment variable properly (see -h for more info)" exit 1 fi # Make sure we can execute mysqldump command TEMP=`which $MYSQLDUMP` if [ $? != 0 ] ; then echo "Could not find mysqldump utility" echo "Set MYSQLDUMP environment variable properly (see -h for more info)" exit 1 fi CMD="$MYSQL -h$DBHOST -u$SQLUSER" DUMP_CMD="${MYSQLDUMP} -h$DBHOST -u$SQLUSER $DUMP_OPTS" case $1 in create) # Create SER database and users prompt_pw create_db exit $? ;; drop) # Drop SER database and users prompt_pw drop_db exit $? ;; update-data) # Update initial data prompt_pw update_db_data exit $? ;; backup) # backup SER database shift if [ $# -eq 1 ] ; then prompt_pw $DUMP_CMD "$PW" $MYSQL_OPTS ${DBNAME} > $1 elif [ $# -eq 0 ] ; then prompt_pw $DUMP_CMD "$PW" $MYSQL_OPTS ${DBNAME} else usage exit 1 fi exit $? ;; restore) # restore SER database shift if [ $# -eq 1 ]; then prompt_pw sql_query $DBNAME < $1 elif [ $# -eq 0 ] ; then prompt_pw cat | sql_query $DBNAME else usage exit 1 fi exit $? ;; *) echo "Unknown command '$1'" usage exit 1; ;; esac