#!/bin/bash -e # # Copyright 2014 # The Cloudscaling Group, Inc. # # 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. # usage() { cat << EOF Set up a local MySQL database for use with ec2api. This script will create a 'ec2api' database that is accessible only on localhost by user 'ec2api' with password 'ec2api'. Usage: ec2api-db-setup [options] Options: select a distro type (rpm or debian) --help | -h Print usage information. --password | -p Specify the password for the 'ec2api' MySQL user that will use to connect to the 'ec2api' MySQL database. By default, the password 'ec2api' will be used. --rootpw | -r 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 $PACKAGE_INSTALL mysql-server else $PACKAGE_INSTALL -y mysql-server fi } start_mysql_server() { $SERVICE_START } check_mysql_credentials() { echo "SELECT 1;" | mysql --protocol=TCP -u root --password=${MYSQL_ROOT_PW} > /dev/null echo $? } MYSQL_EC2API_PW_DEFAULT="ec2api" MYSQL_EC2API_PW=${MYSQL_EC2API_PW_DEFAULT} EC2API_CONFIG="/etc/ec2api/ec2api.conf" ASSUME_YES="" ELEVATE="" # Check for root privileges if [[ $EUID -ne 0 ]] ; then echo "This operation requires superuser privileges, using sudo:" if sudo -l > /dev/null ; then ELEVATE="sudo" else exit 1 fi fi case "$1" in rpm) echo "Installing on an RPM system." PACKAGE_INSTALL="$ELEVATE yum install" PACKAGE_STATUS="rpm -q" SERVICE_MYSQLD="mysqld" SERVICE_START="$ELEVATE service $SERVICE_MYSQLD start" SERVICE_STATUS="service $SERVICE_MYSQLD status" SERVICE_ENABLE="$ELEVATE chkconfig" ;; deb) echo "Installing on a Debian system." PACKAGE_INSTALL="$ELEVATE apt-get install" PACKAGE_STATUS="dpkg-query -S" SERVICE_MYSQLD="mysql" SERVICE_START="$ELEVATE service $SERVICE_MYSQLD start" SERVICE_STATUS="$ELEVATE service $SERVICE_MYSQLD status" SERVICE_ENABLE="" ;; *) usage ;; esac while [ $# -gt 0 ] do case "$1" in -h|--help) usage ;; -p|--password) shift MYSQL_EC2API_PW=${1} ;; -r|--rootpw) shift MYSQL_ROOT_PW=${1} ;; -y|--yes) ASSUME_YES="yes" ;; *) # ignore ;; esac shift done # Make sure MySQL is installed. NEW_MYSQL_INSTALL=0 if ! $PACKAGE_STATUS mysql-server && ! $PACKAGE_STATUS mariadb-server && ! $PACKAGE_STATUS mariadb-galera-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_STATUS > /dev/null then if [ -z "${ASSUME_YES}" ] ; then printf "$SERVICE_MYSQLD is not running. Would you like to start it now? (y/n): " read response case "$response" in y|Y) ;; n|N) echo "$SERVICE_MYSQLD must be running. Please start it before proceeding." exit 0 ;; *) echo "Invalid response." exit 1 esac fi start_mysql_server # If we both installed and started, ensure it starts at boot [ $NEW_MYSQL_INSTALL -eq 1 ] && $SERVICE_ENABLE $SERVICE_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 --protocol=TCP -u root if ! [ $? -eq 0 ] ; then echo "Failed to set password for 'root' MySQL user." exit 1 fi elif [ ! "${MYSQL_ROOT_PW+defined}" ] ; then PW_OK=0 while ! [ $PW_OK -eq 1 ]; do printf "Please enter the password for the 'root' MySQL user: " read -s MYSQL_ROOT_PW echo if [ $(check_mysql_credentials) -eq 0 ]; then PW_OK=1 fi done fi # Sanity check MySQL credentials. MYSQL_ROOT_PW_ARG="" if [ "${MYSQL_ROOT_PW+defined}" ] then MYSQL_ROOT_PW_ARG="--password=${MYSQL_ROOT_PW}" fi if ! [ $(check_mysql_credentials) -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 'ec2api' database." MYSQL_VERSION=`echo "select version();" | mysql -u root ${MYSQL_ROOT_PW_ARG} | grep -oP -m1 "^\d+(?=\..*)"` if [[ $MYSQL_VERSION -ge 8 ]]; then cat << EOF | mysql --protocol=TCP -u root ${MYSQL_ROOT_PW_ARG} DROP DATABASE IF EXISTS ec2api; CREATE DATABASE IF NOT EXISTS ec2api DEFAULT CHARACTER SET utf8; CREATE USER 'ec2api'@'%' IDENTIFIED BY '${MYSQL_EC2API_PW}'; GRANT ALL ON ec2api.* TO 'ec2api'@'localhost'; GRANT ALL ON ec2api.* TO 'ec2api'@'%'; flush privileges; EOF else cat << EOF | mysql --protocol=TCP -u root ${MYSQL_ROOT_PW_ARG} DROP DATABASE IF EXISTS ec2api; CREATE DATABASE IF NOT EXISTS ec2api DEFAULT CHARACTER SET utf8; GRANT ALL ON ec2api.* TO 'ec2api'@'localhost' IDENTIFIED BY '${MYSQL_EC2API_PW}'; GRANT ALL ON ec2api.* TO 'ec2api'@'%' IDENTIFIED BY '${MYSQL_EC2API_PW}'; flush privileges; EOF fi # Make sure ec2api configuration has the right MySQL password. if [ "${MYSQL_EC2API_PW}" != "${MYSQL_EC2API_PW_DEFAULT}" ] ; then echo "Updating 'ec2api' database password in ${EC2API_CONFIG}" sed -i -e "s/mysql:\/\/ec2api:\(.*\)@/mysql:\/\/ec2api:${MYSQL_EC2API_PW}@/" ${EC2API_CONFIG} fi # override the logging config in ec2api.conf log_conf=$(mktemp /tmp/ec2api-logging.XXXXXXXXXX.conf) cat < $log_conf [loggers] keys=root [handlers] keys=consoleHandler [formatters] keys=simpleFormatter [logger_root] level=INFO handlers=consoleHandler [handler_consoleHandler] class=StreamHandler formatter=simpleFormatter args=(sys.stdout,) [formatter_simpleFormatter] format=%(name)s - %(levelname)s - %(message)s EOF pip install mysqlclient ec2-api-manage --log-config=$log_conf db_sync rm $log_conf # Do a final sanity check on the database. echo "Run final sanity check." echo "SELECT * FROM migrate_version;" | mysql --protocol=TCP -u ec2api --password=${MYSQL_EC2API_PW} ec2api > /dev/null if ! [ $? -eq 0 ] then echo "Final sanity check failed." exit 1 fi echo "Complete!"