Simplify database selection

Do not require every script that sources stackrc to also
source lib/databases.

* Move use_databases() to functions
* Set DATABASE_TYPE in stackrc
* Allow setting DATABASE_TYPE in localrc to work
  (use_database() essentially just sets DATABASE_TYPE at this stage
  so continuing to use it is equivalent)
* Validate DATABASE_TYPE in stack.sh.
* Change sudo to postgresql user to go through root to eliminate
  password prompt
* fix use_database error condition

Change-Id: Ibb080c76e6cd7c6eebbb641a894d54b1dde78ca6
diff --git a/functions b/functions
index 92c8a5f..8ab3eef 100644
--- a/functions
+++ b/functions
@@ -841,6 +841,22 @@
     fi
 }
 
+# Set the database backend to use
+# When called from stackrc/localrc DATABASE_BACKENDS has not been
+# initialized yet, just save the configuration selection and call back later
+# to validate it.
+#  $1 The name of the database backend to use (mysql, postgresql, ...)
+function use_database {
+    if [[ -z "$DATABASE_BACKENDS" ]]; then
+        # The backends haven't initialized yet, just save the selection for now
+        DATABASE_TYPE=$1
+        return
+    fi
+    use_exclusive_service DATABASE_BACKENDS DATABASE_TYPE $1 && return 0
+    ret=$?
+    return $ret
+}
+
 # Toggle enable/disable_service for services that must run exclusive of each other
 #  $1 The name of a variable containing a space-separated list of services
 #  $2 The name of a variable in which to store the enabled service's name
diff --git a/lib/database b/lib/database
index 66fb36f..07e37ae 100644
--- a/lib/database
+++ b/lib/database
@@ -62,15 +62,6 @@
     return 0
 }
 
-# Set the database backend to use
-#  $1 The name of the database backend to use (mysql, postgresql, ...)
-function use_database {
-    use_exclusive_service DATABASE_BACKENDS DATABASE_TYPE $1 && return 0
-    ret=$?
-    echo "Invalid database '$1'"
-    return $ret
-}
-
 # Recreate a given database
 #  $1 The name of the database
 #  $2 The character set/encoding of the database
diff --git a/lib/databases/postgresql b/lib/databases/postgresql
index 81989f2..ee24c8b 100644
--- a/lib/databases/postgresql
+++ b/lib/databases/postgresql
@@ -38,8 +38,8 @@
     start_service postgresql
 
     # If creating the role fails, chances are it already existed. Try to alter it.
-    sudo -u postgres -i psql -c "CREATE ROLE $DATABASE_USER WITH SUPERUSER LOGIN PASSWORD '$DATABASE_PASSWORD'" || \
-    sudo -u postgres -i psql -c "ALTER ROLE $DATABASE_USER WITH SUPERUSER LOGIN PASSWORD '$DATABASE_PASSWORD'"
+    sudo -u root sudo -u postgres -i psql -c "CREATE ROLE $DATABASE_USER WITH SUPERUSER LOGIN PASSWORD '$DATABASE_PASSWORD'" || \
+    sudo -u root sudo -u postgres -i psql -c "ALTER ROLE $DATABASE_USER WITH SUPERUSER LOGIN PASSWORD '$DATABASE_PASSWORD'"
 }
 
 function install_database_postgresql {
diff --git a/stack.sh b/stack.sh
index f250c6b..ec10b11 100755
--- a/stack.sh
+++ b/stack.sh
@@ -29,8 +29,6 @@
 # and ``DISTRO``
 GetDistro
 
-# Import database library (must be loaded before stackrc which sources localrc)
-source $TOP_DIR/lib/database
 
 
 # Settings
@@ -92,6 +90,14 @@
 # Sanity Check
 # ============
 
+# Import database configuration
+source $TOP_DIR/lib/database
+
+# Validate database selection
+# Since DATABASE_BACKENDS is now set, this also gets ENABLED_SERVICES
+# properly configured for the database selection.
+use_database $DATABASE_TYPE || echo "Invalid database '$DATABASE_TYPE'"
+
 # Remove services which were negated in ENABLED_SERVICES
 # using the "-" prefix (e.g., "-rabbit") instead of
 # calling disable_service().
diff --git a/stackrc b/stackrc
index 5689779..01e9556 100644
--- a/stackrc
+++ b/stackrc
@@ -6,12 +6,15 @@
 # Destination path for installation
 DEST=/opt/stack
 
+# Select the default database
+DATABASE_TYPE=mysql
+
 # Specify which services to launch.  These generally correspond to
 # screen tabs. To change the default list, use the ``enable_service`` and
 # ``disable_service`` functions in ``localrc``.
 # For example, to enable Swift add this to ``localrc``:
 # enable_service swift
-ENABLED_SERVICES=g-api,g-reg,key,n-api,n-crt,n-obj,n-cpu,n-net,cinder,c-sch,c-api,c-vol,n-sch,n-novnc,n-xvnc,n-cauth,horizon,mysql,rabbit
+ENABLED_SERVICES=g-api,g-reg,key,n-api,n-crt,n-obj,n-cpu,n-net,cinder,c-sch,c-api,c-vol,n-sch,n-novnc,n-xvnc,n-cauth,horizon,rabbit,$DATABASE_TYPE
 
 # Set the default Nova APIs to enable
 NOVA_ENABLED_APIS=ec2,osapi_compute,metadata