egscripts/egmakedbs/egmakedb

163 lines
3.7 KiB
Bash
Executable file

#!/bin/bash
MYCNF=$HOME/.my.cnf
DBHOST=mysql0
GRANTHOST='%'
[ -f /etc/egscripts/egmakedb.cnf ] && . /etc/egscripts/egmakedb.cnf
SIMULATE=0
usage() {
cat <<EOT
Usage: `basename $0` [ OPTIONS ] user dbname
Create a MySQL database. As well as creating the database, this script will
grant access to the database to the specified user, which must be a real user
on the system, and create an additional MySQL user with the same name as the
database.
OPTIONS
-h - Show this help
-H host - Set database host (Default: $DBHOST)
-c mycnf - Use specified my.cnf file for access and database creation
(Default: $MYCNF)
-g hostspec - Specify the hostname part of the GRANT specification for
user, e.g. GRANT ... TO user@'$GRANTHOST'
-s - Simulate. Just output the SQL to be run to STDOUT.
The script outputs a set of variables on stdout which can be eval'd for
use from other shell commands. These variables are DBHOST DBNAME DBOWNER
DBUSER and DBPASS
EOT
}
# MySQL only allows 16 character user names
make_mysql_username() {
prefix=$1
suffix=$2
# Suffix is optional
if [ -n "$suffix" ] ; then
let comp="15 - ${#suffix}"
echo "${prefix:0:$comp}_${suffix}"
else
echo "${prefix:0:16}"
fi
}
get_next_username() {
user=$1
if [ -z "$user" ] ; then
return
fi
# Only try 99 times
for i in `seq 1 99` ; do
username=`make_mysql_username $user $i`
count=`printf "SELECT COUNT(*) FROM mysql.user WHERE USER = '%s'" $username | $mysql_select`
if [ "$count" -eq 0 ] ; then
echo "${username}"
return
fi
done
}
create_db() {
db=$1
user=$2
if [ -z "$db" ] || [ -z "$user" ] ; then
echo "Err: invalid call to grant_privs() function" >&2
exit 1
fi
# In addition to granting all privileges for $user, create a user
# specific for this db. This will be in the format $user_1, $user_2
# up to $user_99, with the lowest available number being chosen.
dbuser=`get_next_username $user`
if [ -z "$dbuser" ] ; then
echo "Unable to generate a new username for db $db" >&2
exit 1
fi
printf 'CREATE DATABASE `%s`;' $dbname | $mysql
# If a .my.cnf file exists for the main user, assume they
# already have a password set. Otherwise create a new MySQL user
# and a .my.cnf in their home directory.
if [ ! -e /home/${user}/.my.cnf ] ; then
passwd=`pwgen -B 10 1`
extra_grants=" IDENTIFIED BY '$passwd'"
if [ $SIMULATE -eq 1 ] ; then
echo "Create /home/${user}/.my.cnf"
else
if [ "$LOGNAME" != "$user" ] ; then
runasuser="sudo -u $user"
fi
$runasuser egcreatemycnf /home/${user}/.my.cnf $DBHOST $user $passwd
fi
fi
# Grant all privileges on the database to the main user
$mysql <<EOT
GRANT ALL PRIVILEGES ON \`$dbname\`.* TO '$user'@'$GRANTHOST'$extra_grants;
EOT
passwd=`pwgen -B 10 1`
$mysql <<EOT
GRANT ALL PRIVILEGES ON \`$dbname\`.* TO '$dbuser'@'$GRANTHOST' IDENTIFIED BY '$passwd';
EOT
echo "DBHOST=$DBHOST"
echo "DBNAME=$dbname"
echo "DBOWNER=$user"
echo "DBUSER=$dbuser"
echo "DBPASS=$passwd"
}
while getopts "c:H:g:hs" OPT ; do
case $OPT in
c) MYCNF=$OPTARG ;;
g) GRANTHOST=$OPTARG ;;
H) DBHOST=$OPTARG ;;
s) SIMULATE=1 ;;
h) usage ; exit 0 ;;
*) usage ; exit 1 ;;
esac
done
shift $(($OPTIND - 1))
if [ $# -ne 2 ] ; then
usage
exit 1
fi
user=$1
dbname=$2
if [ $SIMULATE -eq 1 ] ; then
mysql="cat"
else
mysql="mysql --defaults-file=$MYCNF -h $DBHOST -s"
fi
# In simulate mode, we still need to do real selects to set up
# variables
mysql_select="mysql --defaults-file=$MYCNF -h $DBHOST -s"
# Do some sanity checks
if ! id $user > /dev/null ; then
exit 1
fi
# Exit on any error
set -e
create_db $dbname $user