Browse code

Add PostgreSQL support to devstack

This patch adds an interface for supporting multiple database backend
types and implemnts support for PostgreSQL. It also adds a function,
use_exclusive_service, which serves as a base for enabling a service
that conflicts with other services. The use_database function uses it,
and it might also be useful for selecting messaging backends.

MySQL is still selected by default. Tested on Fedora 17 and Ubuntu
12.04 with MySQL and PostgreSQL. Implements blueprint postgresql-support

Change-Id: I4b1373e25676fd9a9809fe70cb4a6450a2479174

Terry Wilson authored on 2012/11/02 05:12:39
Showing 14 changed files
... ...
@@ -57,6 +57,15 @@ If the EC2 API is your cup-o-tea, you can create credentials and use euca2ools:
57 57
 
58 58
 You can override environment variables used in `stack.sh` by creating file name `localrc`.  It is likely that you will need to do this to tweak your networking configuration should you need to access your cloud from a different host.
59 59
 
60
+# Database Backend
61
+
62
+Multiple database backends are available. The available databases are defined in the lib/databases directory.
63
+To choose a database backend, add a line to your `localrc` like:
64
+
65
+    use_database postgresql
66
+
67
+By default, the mysql database backend is used.
68
+
60 69
 # RPC Backend
61 70
 
62 71
 Multiple RPC backends are available. Currently, this
63 72
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+python-psycopg2
0 1
new file mode 100644
... ...
@@ -0,0 +1 @@
0
+python-psycopg2
... ...
@@ -836,6 +836,21 @@ function upload_image() {
836 836
     fi
837 837
 }
838 838
 
839
+# Toggle enable/disable_service for services that must run exclusive of each other
840
+#  $1 The name of a variable containing a space-separated list of services
841
+#  $2 The name of a variable in which to store the enabled service's name
842
+#  $3 The name of the service to enable
843
+function use_exclusive_service {
844
+    local options=${!1}
845
+    local selection=$3
846
+    out=$2
847
+    [ -z $selection ] || [[ ! "$options" =~ "$selection" ]] && return 1
848
+    for opt in $options;do
849
+        [[ "$opt" = "$selection" ]] && enable_service $opt || disable_service $opt
850
+    done
851
+    eval "$out=$selection"
852
+    return 0
853
+}
839 854
 
840 855
 # Wrapper for ``yum`` to set proxy environment variables
841 856
 # Uses globals ``OFFLINE``, ``*_proxy`
... ...
@@ -112,7 +112,9 @@ function configure_cinder() {
112 112
     iniset $CINDER_CONF DEFAULT volume_group $VOLUME_GROUP
113 113
     iniset $CINDER_CONF DEFAULT volume_name_template ${VOLUME_NAME_PREFIX}%s
114 114
     iniset $CINDER_CONF DEFAULT iscsi_helper tgtadm
115
-    iniset $CINDER_CONF DEFAULT sql_connection $BASE_SQL_CONN/cinder?charset=utf8
115
+    local dburl
116
+    database_connection_url dburl cinder
117
+    iniset $CINDER_CONF DEFAULT sql_connection $dburl
116 118
     iniset $CINDER_CONF DEFAULT api_paste_config $CINDER_API_PASTE_INI
117 119
     iniset $CINDER_CONF DEFAULT root_helper "sudo ${CINDER_ROOTWRAP}"
118 120
     iniset $CINDER_CONF DEFAULT osapi_volume_extension cinder.api.openstack.volume.contrib.standard_extensions
... ...
@@ -141,10 +143,9 @@ function init_cinder() {
141 141
     # Force nova volumes off
142 142
     NOVA_ENABLED_APIS=$(echo $NOVA_ENABLED_APIS | sed "s/osapi_volume,//")
143 143
 
144
-    if is_service_enabled mysql; then
144
+    if is_service_enabled $DATABASE_BACKENDS; then
145 145
         # (re)create cinder database
146
-        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS cinder;'
147
-        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE cinder;'
146
+        recreate_database cinder utf8
148 147
 
149 148
         # (re)create cinder database
150 149
         $CINDER_BIN_DIR/cinder-manage db sync
151 150
new file mode 100644
... ...
@@ -0,0 +1,103 @@
0
+# lib/database
1
+# Interface for interacting with different database backends
2
+
3
+# Dependencies:
4
+# DATABASE_BACKENDS variable must contain a list of available database backends
5
+# DATABASE_TYPE variable must be set
6
+
7
+# Each database must implement four functions:
8
+#   recreate_database_$DATABASE_TYPE
9
+#   install_database_$DATABASE_TYPE
10
+#   configure_database_$DATABASE_TYPE
11
+#   database_connection_url_$DATABASE_TYPE
12
+#
13
+# and call register_database $DATABASE_TYPE
14
+
15
+# Save trace setting
16
+XTRACE=$(set +o | grep xtrace)
17
+set +o xtrace
18
+
19
+# Register a database backend
20
+#  $1 The name of the database backend
21
+function register_database {
22
+    [ -z "$DATABASE_BACKENDS" ] && DATABASE_BACKENDS=$1 || DATABASE_BACKENDS+=" $1"
23
+}
24
+
25
+for f in $TOP_DIR/lib/databases/*; do source $f; done
26
+
27
+# Set the database type based on the configuration
28
+function initialize_database_backends {
29
+    for backend in $DATABASE_BACKENDS; do
30
+        is_service_enabled $backend && DATABASE_TYPE=$backend
31
+    done
32
+
33
+    [ -z "$DATABASE_TYPE" ] && return 1
34
+
35
+    # For backward-compatibility, read in the MYSQL_HOST/USER variables and use
36
+    # them as the default values for the DATABASE_HOST/USER variables.
37
+    MYSQL_HOST=${MYSQL_HOST:-localhost}
38
+    MYSQL_USER=${MYSQL_USER:-root}
39
+
40
+    DATABASE_HOST=${DATABASE_HOST:-${MYSQL_HOST}}
41
+    DATABASE_USER=${DATABASE_USER:-${MYSQL_USER}}
42
+
43
+    if [ -n "$MYSQL_PASSWORD" ]; then
44
+        DATABASE_PASSWORD=$MYSQL_PASSWORD
45
+    else
46
+        read_password DATABASE_PASSWORD "ENTER A PASSWORD TO USE FOR THE DATABASE."
47
+    fi
48
+
49
+    # We configure Nova, Horizon, Glance and Keystone to use MySQL as their
50
+    # database server.  While they share a single server, each has their own
51
+    # database and tables.
52
+
53
+    # By default this script will install and configure MySQL.  If you want to
54
+    # use an existing server, you can pass in the user/password/host parameters.
55
+    # You will need to send the same ``DATABASE_PASSWORD`` to every host if you are doing
56
+    # a multi-node DevStack installation.
57
+
58
+    # NOTE: Don't specify ``/db`` in this string so we can use it for multiple services
59
+    BASE_SQL_CONN=${BASE_SQL_CONN:-${DATABASE_TYPE}://$DATABASE_USER:$DATABASE_PASSWORD@$DATABASE_HOST}
60
+
61
+    return 0
62
+}
63
+
64
+# Set the database backend to use
65
+#  $1 The name of the database backend to use (mysql, postgresql, ...)
66
+function use_database {
67
+    use_exclusive_service DATABASE_BACKENDS DATABASE_TYPE $1 && return 0
68
+    ret=$?
69
+    echo "Invalid database '$1'"
70
+    return $ret
71
+}
72
+
73
+# Recreate a given database
74
+#  $1 The name of the database
75
+#  $2 The character set/encoding of the database
76
+function recreate_database {
77
+    local db=$1
78
+    local charset=$2
79
+    recreate_database_$DATABASE_TYPE $db $charset
80
+}
81
+
82
+# Install the database
83
+function install_database {
84
+    install_database_$DATABASE_TYPE
85
+}
86
+
87
+# Configure and start the database
88
+function configure_database {
89
+    configure_database_$DATABASE_TYPE
90
+}
91
+
92
+# Generate an SQLAlchemy connection URL and store it in a variable
93
+#  $1 The variable name in which to store the connection URL
94
+#  $2 The name of the database
95
+function database_connection_url {
96
+    local var=$1
97
+    local db=$2
98
+    database_connection_url_$DATABASE_TYPE $var $db
99
+}
100
+
101
+# Restore xtrace
102
+$XTRACE
0 103
new file mode 100644
... ...
@@ -0,0 +1,93 @@
0
+# lib/mysql
1
+# Functions to control the configuration and operation of the MySQL database backend
2
+
3
+# Dependencies:
4
+# DATABASE_{HOST,USER,PASSWORD} must be defined
5
+
6
+# Save trace setting
7
+XTRACE=$(set +o | grep xtrace)
8
+set +o xtrace
9
+
10
+register_database mysql
11
+
12
+function recreate_database_mysql {
13
+    local db=$1
14
+    local charset=$2
15
+    mysql -u$DATABASE_USER -p$DATABASE_PASSWORD -e "DROP DATABASE IF EXISTS $db;"
16
+    mysql -u$DATABASE_USER -p$DATABASE_PASSWORD -e "CREATE DATABASE $db CHARACTER SET $charset;"
17
+}
18
+
19
+function configure_database_mysql {
20
+    echo_summary "Configuring and starting MySQL"
21
+
22
+    if [[ "$os_PACKAGE" = "deb" ]]; then
23
+        MY_CONF=/etc/mysql/my.cnf
24
+        MYSQL=mysql
25
+    else
26
+        MY_CONF=/etc/my.cnf
27
+        MYSQL=mysqld
28
+    fi
29
+
30
+    # Start mysql-server
31
+    if [[ "$os_PACKAGE" = "rpm" ]]; then
32
+        # RPM doesn't start the service
33
+        start_service $MYSQL
34
+        # Set the root password - only works the first time
35
+        sudo mysqladmin -u root password $DATABASE_PASSWORD || true
36
+    fi
37
+    # Update the DB to give user ‘$DATABASE_USER’@’%’ full control of the all databases:
38
+    sudo mysql -uroot -p$DATABASE_PASSWORD -h127.0.0.1 -e "GRANT ALL PRIVILEGES ON *.* TO '$DATABASE_USER'@'%' identified by '$DATABASE_PASSWORD';"
39
+
40
+    # Now update ``my.cnf`` for some local needs and restart the mysql service
41
+
42
+    # Change ‘bind-address’ from localhost (127.0.0.1) to any (0.0.0.0)
43
+    sudo sed -i '/^bind-address/s/127.0.0.1/0.0.0.0/g' $MY_CONF
44
+
45
+    # Set default db type to InnoDB
46
+    if sudo grep -q "default-storage-engine" $MY_CONF; then
47
+        # Change it
48
+        sudo bash -c "source $TOP_DIR/functions; iniset $MY_CONF mysqld default-storage-engine InnoDB"
49
+    else
50
+        # Add it
51
+        sudo sed -i -e "/^\[mysqld\]/ a \
52
+default-storage-engine = InnoDB" $MY_CONF
53
+    fi
54
+
55
+    restart_service $MYSQL
56
+}
57
+
58
+function install_database_mysql {
59
+    if [[ "$os_PACKAGE" = "deb" ]]; then
60
+        # Seed configuration with mysql password so that apt-get install doesn't
61
+        # prompt us for a password upon install.
62
+        cat <<MYSQL_PRESEED | sudo debconf-set-selections
63
+mysql-server-5.1 mysql-server/root_password password $DATABASE_PASSWORD
64
+mysql-server-5.1 mysql-server/root_password_again password $DATABASE_PASSWORD
65
+mysql-server-5.1 mysql-server/start_on_boot boolean true
66
+MYSQL_PRESEED
67
+    fi
68
+
69
+    # while ``.my.cnf`` is not needed for OpenStack to function, it is useful
70
+    # as it allows you to access the mysql databases via ``mysql nova`` instead
71
+    # of having to specify the username/password each time.
72
+    if [[ ! -e $HOME/.my.cnf ]]; then
73
+        cat <<EOF >$HOME/.my.cnf
74
+[client]
75
+user=$DATABASE_USER
76
+password=$DATABASE_PASSWORD
77
+host=$DATABASE_HOST
78
+EOF
79
+        chmod 0600 $HOME/.my.cnf
80
+    fi
81
+    # Install mysql-server
82
+    install_package mysql-server
83
+}
84
+
85
+function database_connection_url_mysql {
86
+    local output=$1
87
+    local db=$2
88
+    eval "$output=$BASE_SQL_CONN/$db?charset=utf8"
89
+}
90
+
91
+# Restore xtrace
92
+$XTRACE
0 93
new file mode 100644
... ...
@@ -0,0 +1,70 @@
0
+# lib/postgresql
1
+# Functions to control the configuration and operation of the PostgreSQL database backend
2
+
3
+# Dependencies:
4
+# DATABASE_{HOST,USER,PASSWORD} must be defined
5
+
6
+# Save trace setting
7
+XTRACE=$(set +o | grep xtrace)
8
+set +o xtrace
9
+
10
+register_database postgresql
11
+
12
+function recreate_database_postgresql {
13
+    local db=$1
14
+    local charset=$2
15
+    # Avoid unsightly error when calling dropdb when the database doesn't exist
16
+    psql -h$DATABASE_HOST -U$DATABASE_USER -dtemplate1 -c "DROP DATABASE IF EXISTS $db"
17
+    createdb -h $DATABASE_HOST -U$DATABASE_USER -l C -T template0 -E $charset $db
18
+}
19
+
20
+function configure_database_postgresql {
21
+    echo_summary "Configuring and starting PostgreSQL"
22
+    if [[ "$os_PACKAGE" = "rpm" ]]; then
23
+        PG_HBA=/var/lib/pgsql/data/pg_hba.conf
24
+        PG_CONF=/var/lib/pgsql/data/postgresql.conf
25
+    else
26
+        PG_DIR=`find /etc/postgresql -name pg_hba.conf|xargs dirname`
27
+        PG_HBA=$PG_DIR/pg_hba.conf
28
+        PG_CONF=$PG_DIR/postgresql.conf
29
+    fi
30
+    sudo [ -e /var/lib/pgsql/data ] || sudo postgresql-setup initdb
31
+    # Listen on all addresses
32
+    sudo sed -i "/listen_addresses/s/.*/listen_addresses = '*'/" $PG_CONF
33
+    # Do password auth from all IPv4 clients
34
+    sudo sed -i "/^host/s/all\s\+127.0.0.1\/32\s\+ident/$DATABASE_USER\t0.0.0.0\/0\tpassword/" $PG_HBA
35
+    # Do password auth for all IPv6 clients
36
+    sudo sed -i "/^host/s/all\s\+::1\/128\s\+ident/$DATABASE_USER\t::0\/0\tpassword/" $PG_HBA
37
+    start_service postgresql
38
+
39
+    # If creating the role fails, chances are it already existed. Try to alter it.
40
+    sudo -u postgres -i psql -c "CREATE ROLE $DATABASE_USER WITH SUPERUSER LOGIN PASSWORD '$DATABASE_PASSWORD'" || \
41
+    sudo -u postgres -i psql -c "ALTER ROLE $DATABASE_USER WITH SUPERUSER LOGIN PASSWORD '$DATABASE_PASSWORD'"
42
+}
43
+
44
+function install_database_postgresql {
45
+    echo_summary "Installing postgresql"
46
+    PGPASS=$HOME/.pgpass
47
+    if [[ ! -e $PGPASS ]]; then
48
+        cat <<EOF > $PGPASS
49
+*:*:*:$DATABASE_USER:$DATABASE_PASSWORD
50
+EOF
51
+        chmod 0600 $PGPASS
52
+    else
53
+        sed -i "s/:root:\w\+/:root:$DATABASE_PASSWORD/" $PGPASS
54
+    fi
55
+    if [[ "$os_PACKAGE" = "rpm" ]]; then
56
+        install_package postgresql-server
57
+    else
58
+        install_package postgresql
59
+    fi
60
+}
61
+
62
+function database_connection_url_postgresql {
63
+    local output=$1
64
+    local db=$2
65
+    eval "$output=$BASE_SQL_CONN/$db?client_encoding=utf8"
66
+}
67
+
68
+# Restore xtrace
69
+$XTRACE
... ...
@@ -81,7 +81,9 @@ function configure_glance() {
81 81
     cp $GLANCE_DIR/etc/glance-registry.conf $GLANCE_REGISTRY_CONF
82 82
     iniset $GLANCE_REGISTRY_CONF DEFAULT debug True
83 83
     inicomment $GLANCE_REGISTRY_CONF DEFAULT log_file
84
-    iniset $GLANCE_REGISTRY_CONF DEFAULT sql_connection $BASE_SQL_CONN/glance?charset=utf8
84
+    local dburl
85
+    database_connection_url dburl glance
86
+    iniset $GLANCE_REGISTRY_CONF DEFAULT sql_connection $dburl
85 87
     iniset $GLANCE_REGISTRY_CONF DEFAULT use_syslog $SYSLOG
86 88
     iniset $GLANCE_REGISTRY_CONF paste_deploy flavor keystone
87 89
     iniset $GLANCE_REGISTRY_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
... ...
@@ -95,7 +97,7 @@ function configure_glance() {
95 95
     cp $GLANCE_DIR/etc/glance-api.conf $GLANCE_API_CONF
96 96
     iniset $GLANCE_API_CONF DEFAULT debug True
97 97
     inicomment $GLANCE_API_CONF DEFAULT log_file
98
-    iniset $GLANCE_API_CONF DEFAULT sql_connection $BASE_SQL_CONN/glance?charset=utf8
98
+    iniset $GLANCE_API_CONF DEFAULT sql_connection $dburl
99 99
     iniset $GLANCE_API_CONF DEFAULT use_syslog $SYSLOG
100 100
     iniset $GLANCE_API_CONF DEFAULT filesystem_store_datadir $GLANCE_IMAGE_DIR/
101 101
     iniset $GLANCE_API_CONF DEFAULT image_cache_dir $GLANCE_CACHE_DIR/
... ...
@@ -149,8 +151,7 @@ function init_glance() {
149 149
     mkdir -p $GLANCE_CACHE_DIR
150 150
 
151 151
     # (re)create glance database
152
-    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS glance;'
153
-    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE glance CHARACTER SET utf8;'
152
+    recreate_database glance utf8
154 153
 
155 154
     $GLANCE_BIN_DIR/glance-manage db_sync
156 155
 }
... ...
@@ -120,7 +120,9 @@ function configure_heat() {
120 120
     iniset $HEAT_ENGINE_CONF DEFAULT use_syslog $SYSLOG
121 121
     iniset $HEAT_ENGINE_CONF DEFAULT bind_host $HEAT_ENGINE_HOST
122 122
     iniset $HEAT_ENGINE_CONF DEFAULT bind_port $HEAT_ENGINE_PORT
123
-    iniset $HEAT_ENGINE_CONF DEFAULT sql_connection $BASE_SQL_CONN/heat?charset=utf8
123
+    local dburl
124
+    database_connection_url dburl heat
125
+    iniset $HEAT_ENGINE_CONF DEFAULT sql_connection $dburl
124 126
     iniset $HEAT_ENGINE_CONF DEFAULT auth_encryption_key `hexdump -n 16 -v -e '/1 "%02x"' /dev/random`
125 127
 
126 128
     if is_service_enabled rabbit; then
... ...
@@ -185,8 +187,7 @@ function configure_heat() {
185 185
 function init_heat() {
186 186
 
187 187
     # (re)create heat database
188
-    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS heat;'
189
-    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE heat CHARACTER SET utf8;'
188
+    recreate_database heat utf8
190 189
 
191 190
     $HEAT_DIR/bin/heat-db-setup $os_PACKAGE -r $MYSQL_PASSWORD
192 191
     $HEAT_DIR/tools/nova_create_flavors.sh
... ...
@@ -82,9 +82,11 @@ function configure_keystone() {
82 82
     fi
83 83
 
84 84
     # Rewrite stock ``keystone.conf``
85
+    local dburl
86
+    database_connection_url dburl keystone
85 87
     iniset $KEYSTONE_CONF DEFAULT admin_token "$SERVICE_TOKEN"
86 88
     iniset $KEYSTONE_CONF signing token_format "$KEYSTONE_TOKEN_FORMAT"
87
-    iniset $KEYSTONE_CONF sql connection "$BASE_SQL_CONN/keystone?charset=utf8"
89
+    iniset $KEYSTONE_CONF sql connection $dburl
88 90
     iniset $KEYSTONE_CONF ec2 driver "keystone.contrib.ec2.backends.sql.Ec2"
89 91
     sed -e "
90 92
         /^pipeline.*ec2_extension crud_/s|ec2_extension crud_extension|ec2_extension s3_extension crud_extension|;
... ...
@@ -141,8 +143,7 @@ function configure_keystone() {
141 141
 # init_keystone() - Initialize databases, etc.
142 142
 function init_keystone() {
143 143
     # (Re)create keystone database
144
-    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS keystone;'
145
-    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE keystone CHARACTER SET utf8;'
144
+    recreate_database keystone utf8
146 145
 
147 146
     # Initialize keystone database
148 147
     $KEYSTONE_DIR/bin/keystone-manage db_sync
... ...
@@ -296,7 +296,9 @@ function create_nova_conf() {
296 296
     add_nova_opt "s3_port=$S3_SERVICE_PORT"
297 297
     add_nova_opt "osapi_compute_extension=nova.api.openstack.compute.contrib.standard_extensions"
298 298
     add_nova_opt "my_ip=$HOST_IP"
299
-    add_nova_opt "sql_connection=$BASE_SQL_CONN/nova?charset=utf8"
299
+    local dburl
300
+    database_connection_url dburl nova
301
+    add_nova_opt "sql_connection=$dburl"
300 302
     add_nova_opt "libvirt_type=$LIBVIRT_TYPE"
301 303
     add_nova_opt "libvirt_cpu_mode=none"
302 304
     add_nova_opt "instance_name_template=${INSTANCE_NAME_PREFIX}%08x"
... ...
@@ -372,14 +374,12 @@ function init_nova() {
372 372
     # All nova components talk to a central database.  We will need to do this step
373 373
     # only once for an entire cluster.
374 374
 
375
-    if is_service_enabled mysql && is_service_enabled nova; then
375
+    if is_service_enabled $DATABASE_BACKENDS && is_service_enabled nova; then
376 376
         # (Re)create nova database
377
-        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS nova;'
378
-
379 377
         # Explicitly use latin1: to avoid lp#829209, nova expects the database to
380 378
         # use latin1 by default, and then upgrades the database to utf8 (see the
381 379
         # 082_essex.py in nova)
382
-        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE nova CHARACTER SET latin1;'
380
+        recreate_database nova latin1
383 381
 
384 382
         # (Re)create nova database
385 383
         $NOVA_BIN_DIR/nova-manage db sync
... ...
@@ -30,6 +30,8 @@ source $TOP_DIR/functions
30 30
 # and ``DISTRO``
31 31
 GetDistro
32 32
 
33
+# Import database library (must be loaded before stackrc which sources localrc)
34
+source $TOP_DIR/lib/database
33 35
 
34 36
 # Settings
35 37
 # ========
... ...
@@ -37,15 +39,15 @@ GetDistro
37 37
 # ``stack.sh`` is customizable through setting environment variables.  If you
38 38
 # want to override a setting you can set and export it::
39 39
 #
40
-#     export MYSQL_PASSWORD=anothersecret
40
+#     export DATABASE_PASSWORD=anothersecret
41 41
 #     ./stack.sh
42 42
 #
43
-# You can also pass options on a single line ``MYSQL_PASSWORD=simple ./stack.sh``
43
+# You can also pass options on a single line ``DATABASE_PASSWORD=simple ./stack.sh``
44 44
 #
45 45
 # Additionally, you can put any local variables into a ``localrc`` file::
46 46
 #
47
-#     MYSQL_PASSWORD=anothersecret
48
-#     MYSQL_USER=hellaroot
47
+#     DATABASE_PASSWORD=anothersecret
48
+#     DATABASE_USER=hellaroot
49 49
 #
50 50
 # We try to have sensible defaults, so you should be able to run ``./stack.sh``
51 51
 # in most cases.  ``localrc`` is not distributed with DevStack and will never
... ...
@@ -471,23 +473,20 @@ FLAT_INTERFACE=${FLAT_INTERFACE-$GUEST_INTERFACE_DEFAULT}
471 471
 # With Quantum networking the NET_MAN variable is ignored.
472 472
 
473 473
 
474
-# MySQL & (RabbitMQ or Qpid)
475
-# --------------------------
476
-
477
-# We configure Nova, Horizon, Glance and Keystone to use MySQL as their
478
-# database server.  While they share a single server, each has their own
479
-# database and tables.
474
+# Database configuration
475
+# ----------------------
476
+# To select between database backends, add a line to localrc like:
477
+#
478
+#  use_database postgresql
479
+#
480
+# The available database backends are defined in the DATABASE_BACKENDS
481
+# variable defined in stackrc. By default, MySQL is enabled as the database
482
+# backend.
480 483
 
481
-# By default this script will install and configure MySQL.  If you want to
482
-# use an existing server, you can pass in the user/password/host parameters.
483
-# You will need to send the same ``MYSQL_PASSWORD`` to every host if you are doing
484
-# a multi-node DevStack installation.
485
-MYSQL_HOST=${MYSQL_HOST:-localhost}
486
-MYSQL_USER=${MYSQL_USER:-root}
487
-read_password MYSQL_PASSWORD "ENTER A PASSWORD TO USE FOR MYSQL."
484
+initialize_database_backends && echo "Using $DATABASE_TYPE database backend" || echo "No database enabled"
488 485
 
489
-# NOTE: Don't specify ``/db`` in this string so we can use it for multiple services
490
-BASE_SQL_CONN=${BASE_SQL_CONN:-mysql://$MYSQL_USER:$MYSQL_PASSWORD@$MYSQL_HOST}
486
+# RabbitMQ or Qpid
487
+# --------------------------
491 488
 
492 489
 # Rabbit connection info
493 490
 if is_service_enabled rabbit; then
... ...
@@ -746,32 +745,8 @@ elif is_service_enabled zeromq; then
746 746
     fi
747 747
 fi
748 748
 
749
-if is_service_enabled mysql; then
750
-
751
-    if [[ "$os_PACKAGE" = "deb" ]]; then
752
-        # Seed configuration with mysql password so that apt-get install doesn't
753
-        # prompt us for a password upon install.
754
-        cat <<MYSQL_PRESEED | sudo debconf-set-selections
755
-mysql-server-5.1 mysql-server/root_password password $MYSQL_PASSWORD
756
-mysql-server-5.1 mysql-server/root_password_again password $MYSQL_PASSWORD
757
-mysql-server-5.1 mysql-server/start_on_boot boolean true
758
-MYSQL_PRESEED
759
-    fi
760
-
761
-    # while ``.my.cnf`` is not needed for OpenStack to function, it is useful
762
-    # as it allows you to access the mysql databases via ``mysql nova`` instead
763
-    # of having to specify the username/password each time.
764
-    if [[ ! -e $HOME/.my.cnf ]]; then
765
-        cat <<EOF >$HOME/.my.cnf
766
-[client]
767
-user=$MYSQL_USER
768
-password=$MYSQL_PASSWORD
769
-host=$MYSQL_HOST
770
-EOF
771
-        chmod 0600 $HOME/.my.cnf
772
-    fi
773
-    # Install mysql-server
774
-    install_package mysql-server
749
+if is_service_enabled $DATABASE_BACKENDS; then
750
+    install_database
775 751
 fi
776 752
 
777 753
 if is_service_enabled horizon; then
... ...
@@ -993,46 +968,10 @@ elif is_service_enabled qpid; then
993 993
 fi
994 994
 
995 995
 
996
-# Mysql
997
-# -----
998
-
999
-if is_service_enabled mysql; then
1000
-    echo_summary "Configuring and starting MySQL"
1001
-
1002
-    if [[ "$os_PACKAGE" = "deb" ]]; then
1003
-        MY_CONF=/etc/mysql/my.cnf
1004
-        MYSQL=mysql
1005
-    else
1006
-        MY_CONF=/etc/my.cnf
1007
-        MYSQL=mysqld
1008
-    fi
1009
-
1010
-    # Start mysql-server
1011
-    if [[ "$os_PACKAGE" = "rpm" ]]; then
1012
-        # RPM doesn't start the service
1013
-        start_service $MYSQL
1014
-        # Set the root password - only works the first time
1015
-        sudo mysqladmin -u root password $MYSQL_PASSWORD || true
1016
-    fi
1017
-    # Update the DB to give user ‘$MYSQL_USER’@’%’ full control of the all databases:
1018
-    sudo mysql -uroot -p$MYSQL_PASSWORD -h127.0.0.1 -e "GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_USER'@'%' identified by '$MYSQL_PASSWORD';"
1019
-
1020
-    # Now update ``my.cnf`` for some local needs and restart the mysql service
1021
-
1022
-    # Change ‘bind-address’ from localhost (127.0.0.1) to any (0.0.0.0)
1023
-    sudo sed -i '/^bind-address/s/127.0.0.1/0.0.0.0/g' $MY_CONF
1024
-
1025
-    # Set default db type to InnoDB
1026
-    if sudo grep -q "default-storage-engine" $MY_CONF; then
1027
-        # Change it
1028
-        sudo bash -c "source $TOP_DIR/functions; iniset $MY_CONF mysqld default-storage-engine InnoDB"
1029
-    else
1030
-        # Add it
1031
-        sudo sed -i -e "/^\[mysqld\]/ a \
1032
-default-storage-engine = InnoDB" $MY_CONF
1033
-    fi
1034
-
1035
-    restart_service $MYSQL
996
+# Configure database
997
+# ------------------
998
+if is_service_enabled $DATABASE_BACKENDS; then
999
+    configure_database
1036 1000
 fi
1037 1001
 
1038 1002
 if [ -z "$SCREEN_HARDSTATUS" ]; then
... ...
@@ -1283,7 +1222,9 @@ if is_service_enabled quantum; then
1283 1283
     Q_PLUGIN_CONF_FILE=$Q_PLUGIN_CONF_PATH/$Q_PLUGIN_CONF_FILENAME
1284 1284
     cp $QUANTUM_DIR/$Q_PLUGIN_CONF_FILE /$Q_PLUGIN_CONF_FILE
1285 1285
 
1286
-    iniset /$Q_PLUGIN_CONF_FILE DATABASE sql_connection mysql:\/\/$MYSQL_USER:$MYSQL_PASSWORD@$MYSQL_HOST\/$Q_DB_NAME?charset=utf8
1286
+    database_connection_url dburl $Q_DB_NAME
1287
+    iniset /$Q_PLUGIN_CONF_FILE DATABASE sql_connection $dburl
1288
+    unset dburl
1287 1289
 
1288 1290
     Q_CONF_FILE=/etc/quantum/quantum.conf
1289 1291
     cp $QUANTUM_DIR/etc/quantum.conf $Q_CONF_FILE
... ...
@@ -1309,12 +1250,11 @@ if is_service_enabled q-svc; then
1309 1309
     cp $QUANTUM_DIR/etc/api-paste.ini $Q_API_PASTE_FILE
1310 1310
     cp $QUANTUM_DIR/etc/policy.json $Q_POLICY_FILE
1311 1311
 
1312
-    if is_service_enabled mysql; then
1313
-            mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "DROP DATABASE IF EXISTS $Q_DB_NAME;"
1314
-            mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "CREATE DATABASE IF NOT EXISTS $Q_DB_NAME CHARACTER SET utf8;"
1315
-        else
1316
-            echo "mysql must be enabled in order to use the $Q_PLUGIN Quantum plugin."
1317
-            exit 1
1312
+    if is_service_enabled $DATABASE_BACKENDS; then
1313
+        recreate_database $Q_DB_NAME utf8
1314
+    else
1315
+        echo "A database must be enabled in order to use the $Q_PLUGIN Quantum plugin."
1316
+        exit 1
1318 1317
     fi
1319 1318
 
1320 1319
     # Update either configuration file with plugin
... ...
@@ -1974,7 +1914,7 @@ if is_service_enabled q-svc; then
1974 1974
         fi
1975 1975
    fi
1976 1976
 
1977
-elif is_service_enabled mysql && is_service_enabled nova; then
1977
+elif is_service_enabled $DATABASE_BACKENDS && is_service_enabled nova; then
1978 1978
     # Create a small network
1979 1979
     $NOVA_BIN_DIR/nova-manage network create "$PRIVATE_NETWORK_NAME" $FIXED_RANGE 1 $FIXED_NETWORK_SIZE $NETWORK_CREATE_ARGS
1980 1980
 
... ...
@@ -15,6 +15,9 @@ TOP_DIR=$(cd $(dirname "$0") && pwd)
15 15
 # Import common functions
16 16
 source $TOP_DIR/functions
17 17
 
18
+# Import database library
19
+source $TOP_DIR/lib/database
20
+
18 21
 # Load local configuration
19 22
 source $TOP_DIR/stackrc
20 23
 
... ...
@@ -102,6 +105,10 @@ if [[ -n "$UNSTACK_ALL" ]]; then
102 102
         stop_service mysql
103 103
     fi
104 104
 
105
+    if is_service_enabled postgresql; then
106
+        stop_service postgresql
107
+    fi
108
+
105 109
     # Stop rabbitmq-server
106 110
     if is_service_enabled rabbit; then
107 111
         stop_service rabbitmq-server