Browse code

Merge "Add PostgreSQL support to devstack"

Jenkins authored on 2012/11/04 21:34:31
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`
... ...
@@ -117,7 +117,9 @@ function configure_cinder() {
117 117
     iniset $CINDER_CONF DEFAULT volume_group $VOLUME_GROUP
118 118
     iniset $CINDER_CONF DEFAULT volume_name_template ${VOLUME_NAME_PREFIX}%s
119 119
     iniset $CINDER_CONF DEFAULT iscsi_helper tgtadm
120
-    iniset $CINDER_CONF DEFAULT sql_connection $BASE_SQL_CONN/cinder?charset=utf8
120
+    local dburl
121
+    database_connection_url dburl cinder
122
+    iniset $CINDER_CONF DEFAULT sql_connection $dburl
121 123
     iniset $CINDER_CONF DEFAULT api_paste_config $CINDER_API_PASTE_INI
122 124
     iniset $CINDER_CONF DEFAULT root_helper "sudo ${CINDER_ROOTWRAP}"
123 125
     iniset $CINDER_CONF DEFAULT osapi_volume_extension cinder.api.openstack.volume.contrib.standard_extensions
... ...
@@ -146,10 +148,9 @@ function init_cinder() {
146 146
     # Force nova volumes off
147 147
     NOVA_ENABLED_APIS=$(echo $NOVA_ENABLED_APIS | sed "s/osapi_volume,//")
148 148
 
149
-    if is_service_enabled mysql; then
149
+    if is_service_enabled $DATABASE_BACKENDS; then
150 150
         # (re)create cinder database
151
-        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS cinder;'
152
-        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE cinder;'
151
+        recreate_database cinder utf8
153 152
 
154 153
         # (re)create cinder database
155 154
         $CINDER_BIN_DIR/cinder-manage db sync
156 155
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
... ...
@@ -83,7 +83,9 @@ function configure_glance() {
83 83
     cp $GLANCE_DIR/etc/glance-registry.conf $GLANCE_REGISTRY_CONF
84 84
     iniset $GLANCE_REGISTRY_CONF DEFAULT debug True
85 85
     inicomment $GLANCE_REGISTRY_CONF DEFAULT log_file
86
-    iniset $GLANCE_REGISTRY_CONF DEFAULT sql_connection $BASE_SQL_CONN/glance?charset=utf8
86
+    local dburl
87
+    database_connection_url dburl glance
88
+    iniset $GLANCE_REGISTRY_CONF DEFAULT sql_connection $dburl
87 89
     iniset $GLANCE_REGISTRY_CONF DEFAULT use_syslog $SYSLOG
88 90
     iniset $GLANCE_REGISTRY_CONF paste_deploy flavor keystone
89 91
     iniset $GLANCE_REGISTRY_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
... ...
@@ -100,7 +102,7 @@ function configure_glance() {
100 100
     cp $GLANCE_DIR/etc/glance-api.conf $GLANCE_API_CONF
101 101
     iniset $GLANCE_API_CONF DEFAULT debug True
102 102
     inicomment $GLANCE_API_CONF DEFAULT log_file
103
-    iniset $GLANCE_API_CONF DEFAULT sql_connection $BASE_SQL_CONN/glance?charset=utf8
103
+    iniset $GLANCE_API_CONF DEFAULT sql_connection $dburl
104 104
     iniset $GLANCE_API_CONF DEFAULT use_syslog $SYSLOG
105 105
     iniset $GLANCE_API_CONF DEFAULT filesystem_store_datadir $GLANCE_IMAGE_DIR/
106 106
     iniset $GLANCE_API_CONF DEFAULT image_cache_dir $GLANCE_CACHE_DIR/
... ...
@@ -157,8 +159,7 @@ function init_glance() {
157 157
     mkdir -p $GLANCE_CACHE_DIR
158 158
 
159 159
     # (re)create glance database
160
-    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS glance;'
161
-    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE glance CHARACTER SET utf8;'
160
+    recreate_database glance utf8
162 161
 
163 162
     $GLANCE_BIN_DIR/glance-manage db_sync
164 163
 
... ...
@@ -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
... ...
@@ -86,9 +86,11 @@ function configure_keystone() {
86 86
     fi
87 87
 
88 88
     # Rewrite stock ``keystone.conf``
89
+    local dburl
90
+    database_connection_url dburl keystone
89 91
     iniset $KEYSTONE_CONF DEFAULT admin_token "$SERVICE_TOKEN"
90 92
     iniset $KEYSTONE_CONF signing token_format "$KEYSTONE_TOKEN_FORMAT"
91
-    iniset $KEYSTONE_CONF sql connection "$BASE_SQL_CONN/keystone?charset=utf8"
93
+    iniset $KEYSTONE_CONF sql connection $dburl
92 94
     iniset $KEYSTONE_CONF ec2 driver "keystone.contrib.ec2.backends.sql.Ec2"
93 95
     sed -e "
94 96
         /^pipeline.*ec2_extension crud_/s|ec2_extension crud_extension|ec2_extension s3_extension crud_extension|;
... ...
@@ -145,8 +147,7 @@ function configure_keystone() {
145 145
 # init_keystone() - Initialize databases, etc.
146 146
 function init_keystone() {
147 147
     # (Re)create keystone database
148
-    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS keystone;'
149
-    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE keystone CHARACTER SET utf8;'
148
+    recreate_database keystone utf8
150 149
 
151 150
     # Initialize keystone database
152 151
     $KEYSTONE_DIR/bin/keystone-manage db_sync
... ...
@@ -302,7 +302,9 @@ function create_nova_conf() {
302 302
     add_nova_opt "s3_port=$S3_SERVICE_PORT"
303 303
     add_nova_opt "osapi_compute_extension=nova.api.openstack.compute.contrib.standard_extensions"
304 304
     add_nova_opt "my_ip=$HOST_IP"
305
-    add_nova_opt "sql_connection=$BASE_SQL_CONN/nova?charset=utf8"
305
+    local dburl
306
+    database_connection_url dburl nova
307
+    add_nova_opt "sql_connection=$dburl"
306 308
     add_nova_opt "libvirt_type=$LIBVIRT_TYPE"
307 309
     add_nova_opt "libvirt_cpu_mode=none"
308 310
     add_nova_opt "instance_name_template=${INSTANCE_NAME_PREFIX}%08x"
... ...
@@ -378,14 +380,12 @@ function init_nova() {
378 378
     # All nova components talk to a central database.  We will need to do this step
379 379
     # only once for an entire cluster.
380 380
 
381
-    if is_service_enabled mysql && is_service_enabled nova; then
381
+    if is_service_enabled $DATABASE_BACKENDS && is_service_enabled nova; then
382 382
         # (Re)create nova database
383
-        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS nova;'
384
-
385 383
         # Explicitly use latin1: to avoid lp#829209, nova expects the database to
386 384
         # use latin1 by default, and then upgrades the database to utf8 (see the
387 385
         # 082_essex.py in nova)
388
-        mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE nova CHARACTER SET latin1;'
386
+        recreate_database nova latin1
389 387
 
390 388
         # (Re)create nova database
391 389
         $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
... ...
@@ -990,46 +965,10 @@ elif is_service_enabled qpid; then
990 990
 fi
991 991
 
992 992
 
993
-# Mysql
994
-# -----
995
-
996
-if is_service_enabled mysql; then
997
-    echo_summary "Configuring and starting MySQL"
998
-
999
-    if [[ "$os_PACKAGE" = "deb" ]]; then
1000
-        MY_CONF=/etc/mysql/my.cnf
1001
-        MYSQL=mysql
1002
-    else
1003
-        MY_CONF=/etc/my.cnf
1004
-        MYSQL=mysqld
1005
-    fi
1006
-
1007
-    # Start mysql-server
1008
-    if [[ "$os_PACKAGE" = "rpm" ]]; then
1009
-        # RPM doesn't start the service
1010
-        start_service $MYSQL
1011
-        # Set the root password - only works the first time
1012
-        sudo mysqladmin -u root password $MYSQL_PASSWORD || true
1013
-    fi
1014
-    # Update the DB to give user ‘$MYSQL_USER’@’%’ full control of the all databases:
1015
-    sudo mysql -uroot -p$MYSQL_PASSWORD -h127.0.0.1 -e "GRANT ALL PRIVILEGES ON *.* TO '$MYSQL_USER'@'%' identified by '$MYSQL_PASSWORD';"
1016
-
1017
-    # Now update ``my.cnf`` for some local needs and restart the mysql service
1018
-
1019
-    # Change ‘bind-address’ from localhost (127.0.0.1) to any (0.0.0.0)
1020
-    sudo sed -i '/^bind-address/s/127.0.0.1/0.0.0.0/g' $MY_CONF
1021
-
1022
-    # Set default db type to InnoDB
1023
-    if sudo grep -q "default-storage-engine" $MY_CONF; then
1024
-        # Change it
1025
-        sudo bash -c "source $TOP_DIR/functions; iniset $MY_CONF mysqld default-storage-engine InnoDB"
1026
-    else
1027
-        # Add it
1028
-        sudo sed -i -e "/^\[mysqld\]/ a \
1029
-default-storage-engine = InnoDB" $MY_CONF
1030
-    fi
1031
-
1032
-    restart_service $MYSQL
993
+# Configure database
994
+# ------------------
995
+if is_service_enabled $DATABASE_BACKENDS; then
996
+    configure_database
1033 997
 fi
1034 998
 
1035 999
 if [ -z "$SCREEN_HARDSTATUS" ]; then
... ...
@@ -1280,7 +1219,9 @@ if is_service_enabled quantum; then
1280 1280
     Q_PLUGIN_CONF_FILE=$Q_PLUGIN_CONF_PATH/$Q_PLUGIN_CONF_FILENAME
1281 1281
     cp $QUANTUM_DIR/$Q_PLUGIN_CONF_FILE /$Q_PLUGIN_CONF_FILE
1282 1282
 
1283
-    iniset /$Q_PLUGIN_CONF_FILE DATABASE sql_connection mysql:\/\/$MYSQL_USER:$MYSQL_PASSWORD@$MYSQL_HOST\/$Q_DB_NAME?charset=utf8
1283
+    database_connection_url dburl $Q_DB_NAME
1284
+    iniset /$Q_PLUGIN_CONF_FILE DATABASE sql_connection $dburl
1285
+    unset dburl
1284 1286
 
1285 1287
     Q_CONF_FILE=/etc/quantum/quantum.conf
1286 1288
     cp $QUANTUM_DIR/etc/quantum.conf $Q_CONF_FILE
... ...
@@ -1306,12 +1247,11 @@ if is_service_enabled q-svc; then
1306 1306
     cp $QUANTUM_DIR/etc/api-paste.ini $Q_API_PASTE_FILE
1307 1307
     cp $QUANTUM_DIR/etc/policy.json $Q_POLICY_FILE
1308 1308
 
1309
-    if is_service_enabled mysql; then
1310
-            mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "DROP DATABASE IF EXISTS $Q_DB_NAME;"
1311
-            mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "CREATE DATABASE IF NOT EXISTS $Q_DB_NAME CHARACTER SET utf8;"
1312
-        else
1313
-            echo "mysql must be enabled in order to use the $Q_PLUGIN Quantum plugin."
1314
-            exit 1
1309
+    if is_service_enabled $DATABASE_BACKENDS; then
1310
+        recreate_database $Q_DB_NAME utf8
1311
+    else
1312
+        echo "A database must be enabled in order to use the $Q_PLUGIN Quantum plugin."
1313
+        exit 1
1315 1314
     fi
1316 1315
 
1317 1316
     # Update either configuration file with plugin
... ...
@@ -1971,7 +1911,7 @@ if is_service_enabled q-svc; then
1971 1971
         fi
1972 1972
    fi
1973 1973
 
1974
-elif is_service_enabled mysql && is_service_enabled nova; then
1974
+elif is_service_enabled $DATABASE_BACKENDS && is_service_enabled nova; then
1975 1975
     # Create a small network
1976 1976
     $NOVA_BIN_DIR/nova-manage network create "$PRIVATE_NETWORK_NAME" $FIXED_RANGE 1 $FIXED_NETWORK_SIZE $NETWORK_CREATE_ARGS
1977 1977
 
... ...
@@ -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