Blob Blame History Raw
#!/bin/bash
#
# Copyright (C) 2011 - 2012, Red Hat, Inc.
# Russell Bryant <rbryant@redhat.com>
# Alan Pevec <apevec@redhat.com>
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#

#
# Print --help output and exit.
#

systemctl --version >/dev/null 2>&1 && systemctl=1

# TODO put it in common place for all openstack service
#      (nova, glance and keystone) to use
APP=glance

usage() {

cat << EOF
Set up a local MySQL database for use with openstack-$APP.
This script will create a '$APP' database that is accessible
only on localhost by user '$APP' with password '$APP'.
The setup of MySQL with a multi-server OpenStack installation
is outside of the scope of this simple helper script.

Usage: openstack-$APP-db-setup [options]
Options:
	--help        | -h
		Print usage information.
	--password <pw> | -p <pw>
		Specify the password for the '$APP' MySQL user that $APP will
		use to connect to the '$APP' MySQL database.  By default,
		the password '$APP' will be used.
	--rootpw <pw> | -r <pw>
		Specify the root MySQL password.  If the script installs
		the MySQL server, it will set the root password to this value
		instead of prompting for a password.  If the MySQL server is
		already installed, this password will be used to connect to the
		database instead of having to prompt for it.
	--yes         | -y
		In cases where the script would normally ask for confirmation
		before doing something, such as installing mysql-server,
		just assume yes.  This is useful if you want to run the script
		non-interactively.
EOF

	exit 0
}

install_mysql_server() {
	if [ -z "${ASSUME_YES}" ] ; then
		yum install mysql-server
	else
		yum install -y mysql-server
	fi
}

start_service() {
    if test "$systemctl"; then
        systemctl start $1.service
    else
        service $1 start
    fi
}

service_running() {
    if test "$systemctl"; then
        systemctl status $1.service >/dev/null
    else
        service $1 status >/dev/null
    fi
}

MYSQL_APP_PW_DEFAULT="$APP"
MYSQL_APP_PW=${MYSQL_APP_PW_DEFAULT}
if [ "${APP}" = "glance" ]; then
	APP_CONFIG="/etc/glance/glance-registry.conf"
else
	APP_CONFIG="/etc/$APP/$APP.conf"
fi
ASSUME_YES=""

while [ $# -gt 0 ]
do
	case "$1" in
		-h|--help)
			usage
			;;
		-p|--password)
			shift
			MYSQL_APP_PW=${1}
			;;
		-r|--rootpw)
			shift
			MYSQL_ROOT_PW=${1}
			;;
		-y|--yes)
			ASSUME_YES="yes"
			;;
		*)
			# ignore
			shift
			;;
	esac
	shift
done


# Make sure MySQL is installed.

NEW_MYSQL_INSTALL=0
if ! rpm -q mysql-server > /dev/null
then
	if [ -z "${ASSUME_YES}" ] ; then
		printf "mysql-server is not installed.  Would you like to install it now? (y/n): "
		read response
		case "$response" in
			y|Y)
				;;
			n|N)
				echo "mysql-server must be installed.  Please install it before proceeding."
				exit 0
				;;
			*)
				echo "Invalid response."
				exit 1
		esac
	fi

	NEW_MYSQL_INSTALL=1
	install_mysql_server
fi


# Make sure mysqld is running.

if ! service_running mysqld; then
	if [ -z "${ASSUME_YES}" ] ; then
		printf "mysqld is not running.  Would you like to start it now? (y/n): "
		read response
		case "$response" in
			y|Y)
				;;
			n|N)
				echo "mysqld must be running.  Please start it before proceeding."
				exit 0
				;;
			*)
				echo "Invalid response."
				exit 1
		esac
	fi

	start_service 'mysqld'

	# If we both installed and started, ensure it starts at boot
	[ $NEW_MYSQL_INSTALL -eq 1 ] && chkconfig mysqld on
fi


# Get MySQL root access.

if [ $NEW_MYSQL_INSTALL -eq 1 ]
then
	if [ ! "${MYSQL_ROOT_PW+defined}" ] ; then
		echo "Since this is a fresh installation of MySQL, please set a password for the 'root' mysql user."

		PW_MATCH=0
		while [ $PW_MATCH -eq 0 ]
		do
			printf "Enter new password for 'root' mysql user: "
			read -s MYSQL_ROOT_PW
			echo
			printf "Enter new password again: "
			read -s PW2
			echo
			if [ "${MYSQL_ROOT_PW}" = "${PW2}" ] ; then
				PW_MATCH=1
			else
				echo "Passwords did not match."
			fi
		done
	fi

	echo "UPDATE mysql.user SET password = password('${MYSQL_ROOT_PW}') WHERE user = 'root'; DELETE FROM mysql.user WHERE user = ''; flush privileges;" | mysql -u root
	if ! [ $? -eq 0 ] ; then
		echo "Failed to set password for 'root' MySQL user."
		exit 1
	fi
elif [ ! "${MYSQL_ROOT_PW+defined}" ] ; then
	printf "Please enter the password for the 'root' MySQL user: "
	read -s MYSQL_ROOT_PW
	echo
fi


# Sanity check MySQL credentials.

MYSQL_ROOT_PW_ARG=""
if [ "${MYSQL_ROOT_PW+defined}" ]
then
	MYSQL_ROOT_PW_ARG="--password=${MYSQL_ROOT_PW}"
fi
echo "SELECT 1;" | mysql -u root ${MYSQL_ROOT_PW_ARG} > /dev/null
if ! [ $? -eq 0 ]
then
	echo "Failed to connect to the MySQL server.  Please check your root user credentials."
	exit 1
fi
echo "Verified connectivity to MySQL."


# Now create the db.

echo "Creating '$APP' database."
cat << EOF | mysql -u root ${MYSQL_ROOT_PW_ARG}
CREATE DATABASE $APP;
CREATE USER '$APP'@'localhost' IDENTIFIED BY '${MYSQL_APP_PW}';
CREATE USER '$APP'@'%' IDENTIFIED BY '${MYSQL_APP_PW}';
GRANT ALL ON $APP.* TO '$APP'@'localhost';
GRANT ALL ON $APP.* TO '$APP'@'%';
flush privileges;
EOF


# Make sure $APP configuration has the right MySQL password.

if [ "${MYSQL_APP_PW}" != "${MYSQL_APP_PW_DEFAULT}" ] ; then
	echo "Updating '$APP' database password in ${APP_CONFIG}"
	sed -i -e "s/mysql:\/\/$APP:\(.*\)@/mysql:\/\/$APP:${MYSQL_APP_PW}@/" ${APP_CONFIG}
fi


# Ask openstack-$APP to sync the db.

echo "Asking openstack-$APP to sync the database."
[ "${APP}" = "nova" ] && db_sync='db sync' || db_sync='db_sync'
# Run as $APP user so any newly created (log) files have correct ownership
runuser -s /bin/sh $APP -c "$APP-manage $db_sync"


# Do a final sanity check on the database.

echo "SELECT * FROM migrate_version;" | mysql -u $APP --password=${MYSQL_APP_PW} $APP > /dev/null
if ! [ $? -eq 0 ]
then
	echo "Final sanity check failed.  File a bug report on bugzilla.redhat.com against the openstack-$APP package."
	exit 1
fi

echo "Complete!"