Merge "remove whitebox configuration in tempest.conf"
diff --git a/clean.sh b/clean.sh
index a443ac8..6ceb5a4 100755
--- a/clean.sh
+++ b/clean.sh
@@ -33,6 +33,7 @@
 source $TOP_DIR/lib/database
 source $TOP_DIR/lib/rpc_backend
 
+source $TOP_DIR/lib/oslo
 source $TOP_DIR/lib/tls
 source $TOP_DIR/lib/horizon
 source $TOP_DIR/lib/keystone
diff --git a/exercises/trove.sh b/exercises/trove.sh
new file mode 100755
index 0000000..d48d5fe
--- /dev/null
+++ b/exercises/trove.sh
@@ -0,0 +1,45 @@
+#!/usr/bin/env bash
+
+# **trove.sh**
+
+# Sanity check that trove started if enabled
+
+echo "*********************************************************************"
+echo "Begin DevStack Exercise: $0"
+echo "*********************************************************************"
+
+# This script exits on an error so that errors don't compound and you see
+# only the first error that occurred.
+set -o errexit
+
+# Print the commands being run so that we can see the command that triggers
+# an error.  It is also useful for following allowing as the install occurs.
+set -o xtrace
+
+
+# Settings
+# ========
+
+# Keep track of the current directory
+EXERCISE_DIR=$(cd $(dirname "$0") && pwd)
+TOP_DIR=$(cd $EXERCISE_DIR/..; pwd)
+
+# Import common functions
+source $TOP_DIR/functions
+
+# Import configuration
+source $TOP_DIR/openrc
+
+# Import exercise configuration
+source $TOP_DIR/exerciserc
+
+is_service_enabled trove || exit 55
+
+# can we get a list versions
+curl http://$SERVICE_HOST:8779/ 2>/dev/null | grep -q 'versions' || die $LINENO "Trove API not functioning!"
+
+set +o xtrace
+echo "*********************************************************************"
+echo "SUCCESS: End DevStack Exercise: $0"
+echo "*********************************************************************"
+
diff --git a/files/apache-keystone.template b/files/apache-keystone.template
new file mode 100644
index 0000000..919452a
--- /dev/null
+++ b/files/apache-keystone.template
@@ -0,0 +1,22 @@
+Listen %PUBLICPORT%
+Listen %ADMINPORT%
+
+<VirtualHost *:%PUBLICPORT%>
+    WSGIDaemonProcess keystone-public processes=5 threads=1 user=%USER%
+    WSGIProcessGroup keystone-public
+    WSGIScriptAlias / %PUBLICWSGI%
+    WSGIApplicationGroup %{GLOBAL}
+    ErrorLog /var/log/%APACHE_NAME%/keystone
+    LogLevel debug
+    CustomLog /var/log/%APACHE_NAME%/access.log combined
+</VirtualHost>
+
+<VirtualHost *:%ADMINPORT%>
+    WSGIDaemonProcess keystone-admin processes=5 threads=1 user=%USER%
+    WSGIProcessGroup keystone-admin
+    WSGIScriptAlias / %ADMINWSGI%
+    WSGIApplicationGroup %{GLOBAL}
+    ErrorLog /var/log/%APACHE_NAME%/keystone
+    LogLevel debug
+    CustomLog /var/log/%APACHE_NAME%/access.log combined
+</VirtualHost>
diff --git a/files/apts/trove b/files/apts/trove
new file mode 100644
index 0000000..09dcee8
--- /dev/null
+++ b/files/apts/trove
@@ -0,0 +1 @@
+libxslt1-dev   # testonly
diff --git a/files/ldap/base-config.ldif b/files/ldap/base-config.ldif
new file mode 100644
index 0000000..026d8bc
--- /dev/null
+++ b/files/ldap/base-config.ldif
@@ -0,0 +1,19 @@
+dn: cn=config
+objectClass: olcGlobal
+cn: config
+olcArgsFile: /var/run/slapd/slapd.args
+olcAuthzRegexp: {0}gidNumber=0\+uidNumber=0,cn=peercred,cn=external,cn=auth dn
+ :cn=config
+olcPidFile: /var/run/slapd/slapd.pid
+olcSizeLimit: 10000
+
+dn: cn=schema,cn=config
+objectClass: olcSchemaConfig
+cn: schema
+
+include: file:///etc/openldap/schema/core.ldif
+
+dn: olcDatabase={1}hdb,cn=config
+objectClass: olcHdbConfig
+olcDbDirectory: /var/lib/ldap
+olcSuffix: dc=openstack,dc=org
diff --git a/files/rpms-suse/trove b/files/rpms-suse/trove
new file mode 100644
index 0000000..09dcee8
--- /dev/null
+++ b/files/rpms-suse/trove
@@ -0,0 +1 @@
+libxslt1-dev   # testonly
diff --git a/files/rpms/trove b/files/rpms/trove
new file mode 100644
index 0000000..09dcee8
--- /dev/null
+++ b/files/rpms/trove
@@ -0,0 +1 @@
+libxslt1-dev   # testonly
diff --git a/functions b/functions
index d14c973..bff2e26 100644
--- a/functions
+++ b/functions
@@ -548,12 +548,18 @@
 # Uses global ``OFFLINE``
 # git_clone remote dest-dir branch
 function git_clone {
-    [[ "$OFFLINE" = "True" ]] && return
-
     GIT_REMOTE=$1
     GIT_DEST=$2
     GIT_REF=$3
 
+    if [[ "$OFFLINE" = "True" ]]; then
+        echo "Running in offline mode, clones already exist"
+        # print out the results so we know what change was used in the logs
+        cd $GIT_DEST
+        git show --oneline | head -1
+        return
+    fi
+
     if echo $GIT_REF | egrep -q "^refs"; then
         # If our branch name is a gerrit style refs/changes/...
         if [[ ! -d $GIT_DEST ]]; then
@@ -595,6 +601,10 @@
 
         fi
     fi
+
+    # print out the results so we know what change was used in the logs
+    cd $GIT_DEST
+    git show --oneline | head -1
 }
 
 
@@ -779,6 +789,7 @@
 #   **glance** returns true if any service enabled start with **g-**
 #   **neutron** returns true if any service enabled start with **q-**
 #   **swift** returns true if any service enabled start with **s-**
+#   **trove** returns true if any service enabled start with **tr-**
 #   For backward compatibility if we have **swift** in ENABLED_SERVICES all the
 #   **s-** services will be enabled. This will be deprecated in the future.
 #
@@ -798,6 +809,7 @@
         [[ ${service} == "ceilometer" && ${ENABLED_SERVICES} =~ "ceilometer-" ]] && return 0
         [[ ${service} == "glance" && ${ENABLED_SERVICES} =~ "g-" ]] && return 0
         [[ ${service} == "neutron" && ${ENABLED_SERVICES} =~ "q-" ]] && return 0
+        [[ ${service} == "trove" && ${ENABLED_SERVICES} =~ "tr-" ]] && return 0
         [[ ${service} == "swift" && ${ENABLED_SERVICES} =~ "s-" ]] && return 0
         [[ ${service} == s-* && ${ENABLED_SERVICES} =~ "swift" ]] && return 0
     done
@@ -1158,6 +1170,51 @@
     fi
 }
 
+# Returns true if the directory is on a filesystem mounted via NFS.
+function is_nfs_directory() {
+    local mount_type=`stat -f -L -c %T $1`
+    test "$mount_type" == "nfs"
+}
+
+# Only run the command if the target file (the last arg) is not on an
+# NFS filesystem.
+function _safe_permission_operation() {
+    local args=( $@ )
+    local last
+    local sudo_cmd
+    local dir_to_check
+
+    let last="${#args[*]} - 1"
+
+    dir_to_check=${args[$last]}
+    if [ ! -d "$dir_to_check" ]; then
+        dir_to_check=`dirname "$dir_to_check"`
+    fi
+
+    if is_nfs_directory "$dir_to_check" ; then
+        return 0
+    fi
+
+    if [[ $TRACK_DEPENDS = True ]]; then
+        sudo_cmd="env"
+    else
+        sudo_cmd="sudo"
+    fi
+
+    $sudo_cmd $@
+}
+
+# Only change ownership of a file or directory if it is not on an NFS
+# filesystem.
+function safe_chown() {
+    _safe_permission_operation chown $@
+}
+
+# Only change permissions of a file or directory if it is not on an
+# NFS filesystem.
+function safe_chmod() {
+    _safe_permission_operation chmod $@
+}
 
 # ``pip install -e`` the package, which processes the dependencies
 # using pip before running `setup.py develop`
@@ -1165,23 +1222,26 @@
 # setup_develop directory
 function setup_develop() {
     local project_dir=$1
-    if [[ $TRACK_DEPENDS = True ]]; then
-        SUDO_CMD="env"
-    else
-        SUDO_CMD="sudo"
-    fi
 
     echo "cd $REQUIREMENTS_DIR; $SUDO_CMD python update.py $project_dir"
 
     # Don't update repo if local changes exist
-    if (cd $project_dir && git diff --quiet); then
+    (cd $project_dir && git diff --quiet)
+    local update_requirements=$?
+
+    if [ $update_requirements -eq 0 ]; then
         (cd $REQUIREMENTS_DIR; \
             $SUDO_CMD python update.py $project_dir)
     fi
 
     pip_install -e $project_dir
     # ensure that further actions can do things like setup.py sdist
-    $SUDO_CMD chown -R $STACK_USER $1/*.egg-info
+    safe_chown -R $STACK_USER $1/*.egg-info
+
+    # Undo requirements changes, if we made them
+    if [ $update_requirements -eq 0 ]; then
+        (cd $project_dir && git checkout -- requirements.txt test-requirements.txt setup.py)
+    fi
 }
 
 
@@ -1693,6 +1753,25 @@
 }
 
 
+# This function sets log formatting options for colorizing log
+# output to stdout. It is meant to be called by lib modules.
+# The last two parameters are optional and can be used to specify
+# non-default value for project and user format variables.
+# Defaults are respectively 'project_name' and 'user_name'
+#
+# setup_colorized_logging something.conf SOMESECTION
+function setup_colorized_logging() {
+    local conf_file=$1
+    local conf_section=$2
+    local project_var=${3:-"project_name"}
+    local user_var=${4:-"user_name"}
+    # Add color to logging output
+    iniset $conf_file $conf_section logging_context_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [%(request_id)s %("$user_var")s %("$project_var")s%(color)s] %(instance)s%(color)s%(message)s"
+    iniset $conf_file $conf_section logging_default_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [-%(color)s] %(instance)s%(color)s%(message)s"
+    iniset $conf_file $conf_section logging_debug_format_suffix "from (pid=%(process)d) %(funcName)s %(pathname)s:%(lineno)d"
+    iniset $conf_file $conf_section logging_exception_prefix "%(color)s%(asctime)s.%(msecs)03d TRACE %(name)s %(instance)s"
+}
+
 # Restore xtrace
 $XTRACE
 
diff --git a/lib/apache b/lib/apache
index a2b0534..3a1f6f1 100644
--- a/lib/apache
+++ b/lib/apache
@@ -4,9 +4,10 @@
 # Dependencies:
 # ``functions`` file
 # is_apache_enabled_service
-# change_apache_user_group
 # install_apache_wsgi
 # config_apache_wsgi
+# enable_apache_site
+# disable_apache_site
 # start_apache_server
 # stop_apache_server
 # restart_apache_server
@@ -52,45 +53,47 @@
     return 1
 }
 
-# change_apache_user_group() - Change the User/Group to run Apache server
-function change_apache_user_group(){
-    local stack_user=$@
-    if is_ubuntu; then
-        sudo sed -e "
-            s/^export APACHE_RUN_USER=.*/export APACHE_RUN_USER=${stack_user}/g;
-            s/^export APACHE_RUN_GROUP=.*/export APACHE_RUN_GROUP=${stack_user}/g
-        " -i /etc/${APACHE_NAME}/envvars
-    elif is_fedora; then
-        sudo sed -e "
-            s/^User .*/User ${stack_user}/g;
-            s/^Group .*/Group ${stack_user}/g
-        " -i /etc/${APACHE_NAME}/httpd.conf
-    elif is_suse; then
-        sudo sed -e "
-            s/^User .*/User ${stack_user}/g;
-            s/^Group .*/Group ${stack_user}/g
-        " -i /etc/${APACHE_NAME}/uid.conf
-    else
-        exit_distro_not_supported "apache user and group"
-    fi
-}
-
 # install_apache_wsgi() - Install Apache server and wsgi module
 function install_apache_wsgi() {
     # Apache installation, because we mark it NOPRIME
     if is_ubuntu; then
         # Install apache2, which is NOPRIME'd
         install_package apache2 libapache2-mod-wsgi
+        # WSGI isn't enabled by default, enable it
+        sudo a2enmod wsgi
     elif is_fedora; then
         sudo rm -f /etc/httpd/conf.d/000-*
         install_package httpd mod_wsgi
     elif is_suse; then
         install_package apache2 apache2-mod_wsgi
+        # WSGI isn't enabled by default, enable it
+        sudo a2enmod wsgi
     else
         exit_distro_not_supported "apache installation"
     fi
 }
 
+# enable_apache_site() - Enable a particular apache site
+function enable_apache_site() {
+    local site=$@
+    if is_ubuntu; then
+        sudo a2ensite ${site}
+    elif is_fedora; then
+        # fedora conf.d is only imported if it ends with .conf so this is approx the same
+        sudo mv /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site} /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}.conf
+    fi
+}
+
+# disable_apache_site() - Disable a particular apache site
+function disable_apache_site() {
+    local site=$@
+    if is_ubuntu; then
+        sudo a2dissite ${site}
+    elif is_fedora; then
+        sudo mv /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}.conf /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site}
+    fi
+}
+
 # start_apache_server() - Start running apache server
 function start_apache_server() {
     start_service $APACHE_NAME
diff --git a/lib/baremetal b/lib/baremetal
index b591410..52af420 100644
--- a/lib/baremetal
+++ b/lib/baremetal
@@ -300,7 +300,7 @@
     out=$($BM_IMAGE_BUILD_DIR/bin/disk-image-get-kernel \
             -x -d $TOP_DIR/files -o bm-deploy -i $file)
     if [ $? -ne 0 ]; then
-        die "Failed to get kernel and ramdisk from $file"
+        die $LINENO "Failed to get kernel and ramdisk from $file"
     fi
     XTRACE=$(set +o | grep xtrace)
     set +o xtrace
@@ -448,9 +448,9 @@
        "$BM_FLAVOR_ROOT_DISK" \
        "$mac_1" \
        | grep ' id ' | get_field 2 )
-    [ $? -eq 0 ] || [ "$id" ] || die "Error adding baremetal node"
+    [ $? -eq 0 ] || [ "$id" ] || die $LINENO "Error adding baremetal node"
     id2=$(nova baremetal-interface-add "$id" "$mac_2" )
-    [ $? -eq 0 ] || [ "$id2" ] || die "Error adding interface to barmetal node $id"
+    [ $? -eq 0 ] || [ "$id2" ] || die $LINENO "Error adding interface to barmetal node $id"
 }
 
 
diff --git a/lib/ceilometer b/lib/ceilometer
index 2afbc88..1b04319 100644
--- a/lib/ceilometer
+++ b/lib/ceilometer
@@ -5,7 +5,7 @@
 #   enable_service ceilometer-acompute ceilometer-acentral ceilometer-collector ceilometer-api
 #
 # To ensure Ceilometer alarming services are enabled also, further add to the localrc:
-#   enable_service ceilometer-alarm-notifier ceilometer-alarm-singleton
+#   enable_service ceilometer-alarm-notifier ceilometer-alarm-evaluator
 
 # Dependencies:
 # - functions
@@ -139,13 +139,13 @@
     screen_it ceilometer-collector "ceilometer-collector --config-file $CEILOMETER_CONF"
     screen_it ceilometer-api "ceilometer-api -d -v --log-dir=$CEILOMETER_API_LOG_DIR --config-file $CEILOMETER_CONF"
     screen_it ceilometer-alarm-notifier "ceilometer-alarm-notifier --config-file $CEILOMETER_CONF"
-    screen_it ceilometer-alarm-singleton "ceilometer-alarm-singleton --config-file $CEILOMETER_CONF"
+    screen_it ceilometer-alarm-evaluator "ceilometer-alarm-evaluator --config-file $CEILOMETER_CONF"
 }
 
 # stop_ceilometer() - Stop running processes
 function stop_ceilometer() {
     # Kill the ceilometer screen windows
-    for serv in ceilometer-acompute ceilometer-acentral ceilometer-collector ceilometer-api ceilometer-alarm-notifier ceilometer-alarm-singleton; do
+    for serv in ceilometer-acompute ceilometer-acentral ceilometer-collector ceilometer-api ceilometer-alarm-notifier ceilometer-alarm-evaluator; do
         screen -S $SCREEN_NAME -p $serv -X kill
     done
 }
diff --git a/lib/cinder b/lib/cinder
index 7f1544b..bec65ed 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -255,12 +255,9 @@
         iniset $CINDER_CONF DEFAULT volume_clear none
     fi
 
+    # Format logging
     if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
-        # Add color to logging output
-        iniset $CINDER_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [%(request_id)s %(user_id)s %(project_id)s%(color)s] %(instance)s%(color)s%(message)s"
-        iniset $CINDER_CONF DEFAULT logging_default_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [-%(color)s] %(instance)s%(color)s%(message)s"
-        iniset $CINDER_CONF DEFAULT logging_debug_format_suffix "from (pid=%(process)d) %(funcName)s %(pathname)s:%(lineno)d"
-        iniset $CINDER_CONF DEFAULT logging_exception_prefix "%(color)s%(asctime)s.%(msecs)03d TRACE %(name)s %(instance)s"
+        setup_colorized_logging $CINDER_CONF DEFAULT "project_id" "user_id"
     fi
 
     if [ "$CINDER_DRIVER" == "XenAPINFS" ]; then
diff --git a/lib/glance b/lib/glance
index 64d8b06..7e69682 100644
--- a/lib/glance
+++ b/lib/glance
@@ -39,6 +39,7 @@
 GLANCE_API_PASTE_INI=$GLANCE_CONF_DIR/glance-api-paste.ini
 GLANCE_CACHE_CONF=$GLANCE_CONF_DIR/glance-cache.conf
 GLANCE_POLICY_JSON=$GLANCE_CONF_DIR/policy.json
+GLANCE_SCHEMA_JSON=$GLANCE_CONF_DIR/schema-image.json
 
 # Support entry points installation of console scripts
 if [[ -d $GLANCE_DIR/bin ]]; then
@@ -142,6 +143,7 @@
     iniset $GLANCE_CACHE_CONF DEFAULT admin_password $SERVICE_PASSWORD
 
     cp -p $GLANCE_DIR/etc/policy.json $GLANCE_POLICY_JSON
+    cp -p $GLANCE_DIR/etc/schema-image.json $GLANCE_SCHEMA_JSON
 }
 
 # create_glance_cache_dir() - Part of the init_glance() process
diff --git a/lib/heat b/lib/heat
index ef134ec..ff9473e 100644
--- a/lib/heat
+++ b/lib/heat
@@ -86,10 +86,7 @@
     iniset $HEAT_CONF DEFAULT use_syslog $SYSLOG
     if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
         # Add color to logging output
-        iniset $HEAT_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s%(color)s] %(instance)s%(color)s%(message)s"
-        iniset $HEAT_CONF DEFAULT logging_default_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [-%(color)s] %(instance)s%(color)s%(message)s"
-        iniset $HEAT_CONF DEFAULT logging_debug_format_suffix "from (pid=%(process)d) %(funcName)s %(pathname)s:%(lineno)d"
-        iniset $HEAT_CONF DEFAULT logging_exception_prefix "%(color)s%(asctime)s.%(msecs)03d TRACE %(name)s %(instance)s"
+        setup_colorized_logging $HEAT_CONF DEFAULT
     fi
 
     # keystone authtoken
@@ -122,7 +119,7 @@
     iniset $HEAT_CONF heat_api_cloudwatch bind_port $HEAT_API_CW_PORT
 
     # Set limits to match tempest defaults
-    iniset $HEAT_CONF max_template_size 10240
+    iniset $HEAT_CONF DEFAULT max_template_size 10240
 
     # heat environment
     sudo mkdir -p $HEAT_ENV_DIR
diff --git a/lib/horizon b/lib/horizon
index e55bc15..5973eb2 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -123,8 +123,6 @@
         # Be a good citizen and use the distro tools here
         sudo touch $horizon_conf
         sudo a2ensite horizon.conf
-        # WSGI isn't enabled by default, enable it
-        sudo a2enmod wsgi
     elif is_fedora; then
         if [[ "$os_RELEASE" -ge "18" ]]; then
             # fedora 18 has Require all denied  in its httpd.conf
@@ -132,9 +130,6 @@
             HORIZON_REQUIRE='Require all granted'
         fi
         sudo sed '/^Listen/s/^.*$/Listen 0.0.0.0:80/' -i /etc/httpd/conf/httpd.conf
-    elif is_suse; then
-        # WSGI isn't enabled by default, enable it
-        sudo a2enmod wsgi
     else
         exit_distro_not_supported "apache configuration"
     fi
diff --git a/lib/keystone b/lib/keystone
old mode 100644
new mode 100755
index 535710f..c4b2dff
--- a/lib/keystone
+++ b/lib/keystone
@@ -14,11 +14,13 @@
 #
 # install_keystone
 # configure_keystone
+# _config_keystone_apache_wsgi
 # init_keystone
 # start_keystone
 # create_keystone_accounts
 # stop_keystone
 # cleanup_keystone
+# _cleanup_keystone_apache_wsgi
 
 # Save trace setting
 XTRACE=$(set +o | grep xtrace)
@@ -34,6 +36,7 @@
 KEYSTONE_CONF=$KEYSTONE_CONF_DIR/keystone.conf
 KEYSTONE_PASTE_INI=${KEYSTONE_PASTE_INI:-$KEYSTONE_CONF_DIR/keystone-paste.ini}
 KEYSTONE_AUTH_CACHE_DIR=${KEYSTONE_AUTH_CACHE_DIR:-/var/cache/keystone}
+KEYSTONE_WSGI_DIR=${KEYSTONE_WSGI_DIR:-/var/www/keystone}
 
 KEYSTONECLIENT_DIR=$DEST/python-keystoneclient
 
@@ -44,6 +47,12 @@
 # Select the backend for Tokens
 KEYSTONE_TOKEN_BACKEND=${KEYSTONE_TOKEN_BACKEND:-sql}
 
+# Select the backend for Identity
+KEYSTONE_IDENTITY_BACKEND=${KEYSTONE_IDENTITY_BACKEND:-sql}
+
+# Select the backend for Assignment
+KEYSTONE_ASSIGNMENT_BACKEND=${KEYSTONE_ASSIGNMENT_BACKEND:-sql}
+
 # Select Keystone's token format
 # Choose from 'UUID' and 'PKI'
 KEYSTONE_TOKEN_FORMAT=${KEYSTONE_TOKEN_FORMAT:-PKI}
@@ -63,10 +72,14 @@
 # Set the tenant for service accounts in Keystone
 SERVICE_TENANT_NAME=${SERVICE_TENANT_NAME:-service}
 
+# valid identity backends as per dir keystone/identity/backends
+KEYSTONE_VALID_IDENTITY_BACKENDS=kvs,ldap,pam,sql
+
+# valid assignment backends as per dir keystone/identity/backends
+KEYSTONE_VALID_ASSIGNMENT_BACKENDS=kvs,ldap,sql
 
 # Functions
 # ---------
-
 # cleanup_keystone() - Remove residual data files, anything left over from previous
 # runs that a clean run would need to clean up
 function cleanup_keystone() {
@@ -76,6 +89,33 @@
     :
 }
 
+# _cleanup_keystone_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
+function _cleanup_keystone_apache_wsgi() {
+    sudo rm -f $KEYSTONE_WSGI_DIR/*.wsgi
+    disable_apache_site keystone
+    sudo rm -f /etc/$APACHE_NAME/$APACHE_CONF_DIR/keystone
+}
+
+# _config_keystone_apache_wsgi() - Set WSGI config files of Keystone
+function _config_keystone_apache_wsgi() {
+    sudo mkdir -p $KEYSTONE_WSGI_DIR
+
+    # copy proxy vhost and wsgi file
+    sudo cp $KEYSTONE_DIR/httpd/keystone.py $KEYSTONE_WSGI_DIR/main
+    sudo cp $KEYSTONE_DIR/httpd/keystone.py $KEYSTONE_WSGI_DIR/admin
+
+    sudo cp $FILES/apache-keystone.template /etc/$APACHE_NAME/$APACHE_CONF_DIR/keystone
+    sudo sed -e "
+        s|%PUBLICPORT%|$KEYSTONE_SERVICE_PORT|g;
+        s|%ADMINPORT%|$KEYSTONE_AUTH_PORT|g;
+        s|%APACHE_NAME%|$APACHE_NAME|g;
+        s|%PUBLICWSGI%|$KEYSTONE_WSGI_DIR/main|g;
+        s|%ADMINWSGI%|$KEYSTONE_WSGI_DIR/admin|g;
+        s|%USER%|$STACK_USER|g
+    " -i /etc/$APACHE_NAME/$APACHE_CONF_DIR/keystone
+    enable_apache_site keystone
+}
+
 # configure_keystone() - Set config files, create data dirs, etc
 function configure_keystone() {
     if [[ ! -d $KEYSTONE_CONF_DIR ]]; then
@@ -116,8 +156,14 @@
         iniset $KEYSTONE_CONF DEFAULT member_role_name "_member_"
     fi
 
-    if [[  "$KEYSTONE_IDENTITY_BACKEND" == "ldap"  ]]; then
-        iniset $KEYSTONE_CONF identity driver "keystone.identity.backends.ldap.Identity"
+    # check if identity backend is valid
+    if [[ "$KEYSTONE_VALID_IDENTITY_BACKENDS" =~ "$KEYSTONE_IDENTITY_BACKEND" ]]; then
+        iniset $KEYSTONE_CONF identity driver "keystone.identity.backends.$KEYSTONE_IDENTITY_BACKEND.Identity"
+    fi
+
+    # check if assignment backend is valid
+    if [[ "$KEYSTONE_VALID_ASSIGNMENT_BACKENDS" =~ "$KEYSTONE_ASSIGNMENT_BACKEND" ]]; then
+        iniset $KEYSTONE_CONF assignment driver "keystone.assignment.backends.$KEYSTONE_ASSIGNMENT_BACKEND.Assignment"
     fi
 
     # Set the URL advertised in the ``versions`` structure returned by the '/' route
@@ -188,6 +234,10 @@
     cp $KEYSTONE_DIR/etc/logging.conf.sample $KEYSTONE_CONF_DIR/logging.conf
     iniset $KEYSTONE_CONF_DIR/logging.conf logger_root level "DEBUG"
     iniset $KEYSTONE_CONF_DIR/logging.conf logger_root handlers "devel,production"
+
+    if is_apache_enabled_service key; then
+        _config_keystone_apache_wsgi
+    fi
 }
 
 # create_keystone_accounts() - Sets up common required keystone accounts
@@ -300,6 +350,9 @@
     fi
     git_clone $KEYSTONE_REPO $KEYSTONE_DIR $KEYSTONE_BRANCH
     setup_develop $KEYSTONE_DIR
+    if is_apache_enabled_service key; then
+        install_apache_wsgi
+    fi
 }
 
 # start_keystone() - Start running processes, including screen
@@ -310,8 +363,14 @@
         service_port=$KEYSTONE_SERVICE_PORT_INT
     fi
 
-    # Start Keystone in a screen window
-    screen_it key "cd $KEYSTONE_DIR && $KEYSTONE_DIR/bin/keystone-all --config-file $KEYSTONE_CONF $KEYSTONE_LOG_CONFIG -d --debug"
+    if is_apache_enabled_service key; then
+        restart_apache_server
+        screen_it key "cd $KEYSTONE_DIR && sudo tail -f /var/log/$APACHE_NAME/keystone"
+    else
+        # Start Keystone in a screen window
+        screen_it key "cd $KEYSTONE_DIR && $KEYSTONE_DIR/bin/keystone-all --config-file $KEYSTONE_CONF $KEYSTONE_LOG_CONFIG -d --debug"
+    fi
+
     echo "Waiting for keystone to start..."
     if ! timeout $SERVICE_TIMEOUT sh -c "while ! http_proxy= curl -s http://$SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/ >/dev/null; do sleep 1; done"; then
       die $LINENO "keystone did not start"
diff --git a/lib/ldap b/lib/ldap
index 89b31b2..2a24ccd 100644
--- a/lib/ldap
+++ b/lib/ldap
@@ -8,6 +8,7 @@
 XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
+LDAP_SERVICE_NAME=slapd
 
 # Functions
 # ---------
@@ -24,10 +25,19 @@
         LDAP_ROOTPW_COMMAND=replace
         sudo DEBIAN_FRONTEND=noninteractive apt-get install slapd ldap-utils
         #automatically starts LDAP on ubuntu so no need to call start_ldap
-    elif is_fedora || is_suse; then
+    elif is_fedora; then
         LDAP_OLCDB_NUMBER=2
         LDAP_ROOTPW_COMMAND=add
         start_ldap
+    elif is_suse; then
+        LDAP_OLCDB_NUMBER=1
+        LDAP_ROOTPW_COMMAND=add
+        LDAP_SERVICE_NAME=ldap
+        # SUSE has slappasswd in /usr/sbin/
+        PATH=$PATH:/usr/sbin/
+        sudo slapadd -F /etc/openldap/slapd.d/ -bcn=config -l $FILES/ldap/base-config.ldif
+        sudo sed -i '/^OPENLDAP_START_LDAPI=/s/"no"/"yes"/g' /etc/sysconfig/openldap
+        start_ldap
     fi
 
     printf "generate password file"
@@ -42,7 +52,7 @@
     sudo ldapmodify -Y EXTERNAL -H ldapi:/// -f $TMP_MGR_DIFF_FILE
 
     # On fedora we need to manually add cosine and inetorgperson schemas
-    if is_fedora; then
+    if is_fedora || is_suse; then
         sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/cosine.ldif
         sudo ldapadd -Y EXTERNAL -H ldapi:/// -f /etc/openldap/schema/inetorgperson.ldif
     fi
@@ -64,13 +74,13 @@
 
 # start_ldap() - Start LDAP
 function start_ldap() {
-    sudo service slapd restart
+    sudo service $LDAP_SERVICE_NAME restart
 }
 
 
 # stop_ldap() - Stop LDAP
 function stop_ldap() {
-    sudo service slapd stop
+    sudo service $LDAP_SERVICE_NAME stop
 }
 
 # clear_ldap_state() - Clear LDAP State
diff --git a/lib/neutron b/lib/neutron
index 5664ff2..4a3d1b0 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -534,6 +534,11 @@
         iniset $NEUTRON_CONF quotas quota_security_group_rule -1
     fi
 
+    # Format logging
+    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
+        setup_colorized_logging $NEUTRON_CONF DEFAULT
+    fi
+
     _neutron_setup_rootwrap
 }
 
diff --git a/lib/nova b/lib/nova
index 9b766a9..e5c78d8 100644
--- a/lib/nova
+++ b/lib/nova
@@ -499,12 +499,9 @@
     if [ "$API_RATE_LIMIT" != "True" ]; then
         iniset $NOVA_CONF DEFAULT api_rate_limit "False"
     fi
+    # Format logging
     if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
-        # Add color to logging output
-        iniset $NOVA_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s%(color)s] %(instance)s%(color)s%(message)s"
-        iniset $NOVA_CONF DEFAULT logging_default_format_string "%(asctime)s.%(msecs)03d %(color)s%(levelname)s %(name)s [-%(color)s] %(instance)s%(color)s%(message)s"
-        iniset $NOVA_CONF DEFAULT logging_debug_format_suffix "from (pid=%(process)d) %(funcName)s %(pathname)s:%(lineno)d"
-        iniset $NOVA_CONF DEFAULT logging_exception_prefix "%(color)s%(asctime)s.%(msecs)03d TRACE %(name)s %(instance)s"
+        setup_colorized_logging $NOVA_CONF DEFAULT
     else
         # Show user_name and project_name instead of user_id and project_id
         iniset $NOVA_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s] %(instance)s%(message)s"
@@ -513,7 +510,6 @@
         iniset $NOVA_CONF DEFAULT instance_usage_audit "True"
         iniset $NOVA_CONF DEFAULT instance_usage_audit_period "hour"
         iniset $NOVA_CONF DEFAULT notify_on_state_change "vm_and_task_state"
-        iniset_multiline $NOVA_CONF DEFAULT notification_driver "nova.openstack.common.notifier.rpc_notifier" "ceilometer.compute.nova_notifier"
     fi
 
     # Provide some transition from ``EXTRA_FLAGS`` to ``EXTRA_OPTS``
diff --git a/lib/nova_plugins/hypervisor-fake b/lib/nova_plugins/hypervisor-fake
new file mode 100644
index 0000000..fe0d190
--- /dev/null
+++ b/lib/nova_plugins/hypervisor-fake
@@ -0,0 +1,77 @@
+# lib/nova_plugins/hypervisor-fake
+# Configure the fake hypervisor
+
+# Enable with:
+# VIRT_DRIVER=fake
+
+# Dependencies:
+# ``functions`` file
+# ``nova`` configuration
+
+# install_nova_hypervisor - install any external requirements
+# configure_nova_hypervisor - make configuration changes, including those to other services
+# start_nova_hypervisor - start any external services
+# stop_nova_hypervisor - stop any external services
+# cleanup_nova_hypervisor - remove transient data and cache
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+
+# Entry Points
+# ------------
+
+# clean_nova_hypervisor - Clean up an installation
+function cleanup_nova_hypervisor() {
+    # This function intentionally left blank
+    :
+}
+
+# configure_nova_hypervisor - Set config files, create data dirs, etc
+function configure_nova_hypervisor() {
+    iniset $NOVA_CONF DEFAULT compute_driver "nova.virt.fake.FakeDriver"
+    # Disable arbitrary limits
+    iniset $NOVA_CONF DEFAULT quota_instances -1
+    iniset $NOVA_CONF DEFAULT quota_cores -1
+    iniset $NOVA_CONF DEFAULT quota_ram -1
+    iniset $NOVA_CONF DEFAULT quota_floating_ips -1
+    iniset $NOVA_CONF DEFAULT quota_fixed_ips -1
+    iniset $NOVA_CONF DEFAULT quota_metadata_items -1
+    iniset $NOVA_CONF DEFAULT quota_injected_files -1
+    iniset $NOVA_CONF DEFAULT quota_injected_file_path_bytes -1
+    iniset $NOVA_CONF DEFAULT quota_security_groups -1
+    iniset $NOVA_CONF DEFAULT quota_security_group_rules -1
+    iniset $NOVA_CONF DEFAULT quota_key_pairs -1
+    iniset $NOVA_CONF DEFAULT scheduler_default_filters "RetryFilter,AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter"
+}
+
+# install_nova_hypervisor() - Install external components
+function install_nova_hypervisor() {
+    # This function intentionally left blank
+    :
+}
+
+# start_nova_hypervisor - Start any required external services
+function start_nova_hypervisor() {
+    # This function intentionally left blank
+    :
+}
+
+# stop_nova_hypervisor - Stop any external services
+function stop_nova_hypervisor() {
+    # This function intentionally left blank
+    :
+}
+
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/swift b/lib/swift
index f72beaf..9c80802 100644
--- a/lib/swift
+++ b/lib/swift
@@ -55,7 +55,13 @@
 # swift data. Set ``SWIFT_LOOPBACK_DISK_SIZE`` to the disk size in
 # kilobytes.
 # Default is 1 gigabyte.
-SWIFT_LOOPBACK_DISK_SIZE=${SWIFT_LOOPBACK_DISK_SIZE:-1000000}
+SWIFT_LOOPBACK_DISK_SIZE_DEFAULT=1048576
+# if tempest enabled the default size is 4 Gigabyte.
+if is_service_enabled tempest; then
+    SWIFT_LOOPBACK_DISK_SIZE_DEFAULT=${SWIFT_LOOPBACK_DISK_SIZE:-4194304}
+fi
+
+SWIFT_LOOPBACK_DISK_SIZE=${SWIFT_LOOPBACK_DISK_SIZE:-$SWIFT_LOOPBACK_DISK_SIZE_DEFAULT}
 
 # Set ``SWIFT_EXTRAS_MIDDLEWARE`` to extras middlewares.
 # Default is ``staticweb, tempurl, formpost``
@@ -109,11 +115,11 @@
 # _cleanup_swift_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
 function _cleanup_swift_apache_wsgi() {
     sudo rm -f $SWIFT_APACHE_WSGI_DIR/*.wsgi
-    ! is_fedora && sudo a2dissite proxy-server
+    disable_apache_site proxy-server
     for node_number in ${SWIFT_REPLICAS_SEQ}; do
         for type in object container account; do
             site_name=${type}-server-${node_number}
-            ! is_fedora && sudo a2dissite ${site_name}
+            disable_apache_site ${site_name}
             sudo rm -f /etc/$APACHE_NAME/$APACHE_CONF_DIR/${site_name}
         done
     done
@@ -132,14 +138,15 @@
         s/%PORT%/$proxy_port/g;
         s/%SERVICENAME%/proxy-server/g;
         s/%APACHE_NAME%/${APACHE_NAME}/g;
+        s/%USER%/${STACK_USER}/g;
     " -i ${apache_vhost_dir}/proxy-server
+    enable_apache_site proxy-server
 
     sudo cp ${SWIFT_DIR}/examples/wsgi/proxy-server.wsgi.template ${SWIFT_APACHE_WSGI_DIR}/proxy-server.wsgi
     sudo sed -e "
         /^#/d;/^$/d;
         s/%SERVICECONF%/proxy-server.conf/g;
     " -i ${SWIFT_APACHE_WSGI_DIR}/proxy-server.wsgi
-    ! is_fedora && sudo a2ensite proxy-server
 
     # copy apache vhost file and set name and port
     for node_number in ${SWIFT_REPLICAS_SEQ}; do
@@ -152,8 +159,9 @@
             s/%PORT%/$object_port/g;
             s/%SERVICENAME%/object-server-${node_number}/g;
             s/%APACHE_NAME%/${APACHE_NAME}/g;
+            s/%USER%/${STACK_USER}/g;
         " -i ${apache_vhost_dir}/object-server-${node_number}
-        ! is_fedora && sudo a2ensite object-server-${node_number}
+        enable_apache_site object-server-${node_number}
 
         sudo cp ${SWIFT_DIR}/examples/wsgi/object-server.wsgi.template ${SWIFT_APACHE_WSGI_DIR}/object-server-${node_number}.wsgi
         sudo sed -e "
@@ -167,8 +175,9 @@
             s/%PORT%/$container_port/g;
             s/%SERVICENAME%/container-server-${node_number}/g;
             s/%APACHE_NAME%/${APACHE_NAME}/g;
+            s/%USER%/${STACK_USER}/g;
         " -i ${apache_vhost_dir}/container-server-${node_number}
-        ! is_fedora && sudo a2ensite container-server-${node_number}
+        enable_apache_site container-server-${node_number}
 
         sudo cp ${SWIFT_DIR}/examples/wsgi/container-server.wsgi.template ${SWIFT_APACHE_WSGI_DIR}/container-server-${node_number}.wsgi
         sudo sed -e "
@@ -182,22 +191,16 @@
             s/%PORT%/$account_port/g;
             s/%SERVICENAME%/account-server-${node_number}/g;
             s/%APACHE_NAME%/${APACHE_NAME}/g;
+            s/%USER%/${STACK_USER}/g;
         " -i ${apache_vhost_dir}/account-server-${node_number}
-        ! is_fedora && sudo a2ensite account-server-${node_number}
+        enable_apache_site account-server-${node_number}
 
         sudo cp ${SWIFT_DIR}/examples/wsgi/account-server.wsgi.template ${SWIFT_APACHE_WSGI_DIR}/account-server-${node_number}.wsgi
         sudo sed -e "
              /^#/d;/^$/d;
             s/%SERVICECONF%/account-server\/${node_number}.conf/g;
         " -i ${SWIFT_APACHE_WSGI_DIR}/account-server-${node_number}.wsgi
-
     done
-
-    # run apache server as stack user
-    change_apache_user_group ${STACK_USER}
-
-    # WSGI isn't enabled by default, enable it
-    ! is_fedora && sudo a2enmod wsgi
 }
 
 # configure_swift() - Set config files, create data dirs and loop image
@@ -552,10 +555,6 @@
     fi
 
     if is_apache_enabled_service swift; then
-        # Make sure the apache lock dir is owned by $STACK_USER
-        # for running apache server to avoid failure of restarting
-        # apache server due to permission problem.
-        sudo chown -R $STACK_USER /var/run/lock/$APACHE_NAME
         restart_apache_server
         swift-init --run-dir=${SWIFT_DATA_DIR}/run rest start
         screen_it s-proxy "cd $SWIFT_DIR && sudo tail -f /var/log/$APACHE_NAME/proxy-server"
diff --git a/lib/tempest b/lib/tempest
index bc0b18d..646d42b 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -230,11 +230,6 @@
 
     # Compute
     iniset $TEMPEST_CONF compute change_password_available False
-    # Note(nati) current tempest don't create network for each tenant
-    # so reuse same tenant for now
-    if is_service_enabled neutron; then
-        TEMPEST_ALLOW_TENANT_ISOLATION=${TEMPEST_ALLOW_TENANT_ISOLATION:-False}
-    fi
     iniset $TEMPEST_CONF compute allow_tenant_isolation ${TEMPEST_ALLOW_TENANT_ISOLATION:-True}
     iniset $TEMPEST_CONF compute ssh_user ${DEFAULT_INSTANCE_USER:-cirros} # DEPRECATED
     iniset $TEMPEST_CONF compute network_for_ssh $PRIVATE_NETWORK_NAME
diff --git a/lib/trove b/lib/trove
new file mode 100644
index 0000000..e64ca5f
--- /dev/null
+++ b/lib/trove
@@ -0,0 +1,170 @@
+# lib/trove
+# Functions to control the configuration and operation of the **Trove** service
+
+# Dependencies:
+# ``functions`` file
+# ``DEST``, ``STACK_USER`` must be defined
+# ``SERVICE_{HOST|PROTOCOL|TOKEN}`` must be defined
+
+# ``stack.sh`` calls the entry points in this order:
+#
+# install_trove
+# configure_trove
+# init_trove
+# start_trove
+# stop_trove
+# cleanup_trove
+
+# Save trace setting
+XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+# Defaults
+# --------
+
+NETWORK_GATEWAY=${NETWORK_GATEWAY:-10.0.0.1}
+
+# Set up default configuration
+TROVE_DIR=$DEST/trove
+TROVECLIENT_DIR=$DEST/python-troveclient
+TROVE_CONF_DIR=/etc/trove
+TROVE_LOCAL_CONF_DIR=$TROVE_DIR/etc/trove
+TROVE_AUTH_ENDPOINT=$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT//v$IDENTITY_API_VERSION
+TROVE_AUTH_CACHE_DIR=${TROVE_AUTH_CACHE_DIR:-/var/cache/trove}
+TROVE_BIN_DIR=/usr/local/bin
+
+# create_trove_accounts() - Set up common required trove accounts
+
+# Tenant               User       Roles
+# ------------------------------------------------------------------
+# service              trove     admin        # if enabled
+
+create_trove_accounts() {
+    # Trove
+    SERVICE_TENANT=$(keystone tenant-list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
+    SERVICE_ROLE=$(keystone role-list | awk "/ admin / { print \$2 }")
+
+    if [[ "$ENABLED_SERVICES" =~ "trove" ]]; then
+        TROVE_USER=$(keystone user-create --name=trove \
+                                                  --pass="$SERVICE_PASSWORD" \
+                                                  --tenant_id $SERVICE_TENANT \
+                                                  --email=trove@example.com \
+                                                  | grep " id " | get_field 2)
+        keystone user-role-add --tenant-id $SERVICE_TENANT \
+                               --user-id $TROVE_USER \
+                               --role-id $SERVICE_ROLE
+        if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
+            TROVE_SERVICE=$(keystone service-create \
+                --name=trove \
+                --type=database \
+                --description="Trove Service" \
+                | grep " id " | get_field 2)
+            keystone endpoint-create \
+                --region RegionOne \
+                --service_id $TROVE_SERVICE \
+                --publicurl "http://$SERVICE_HOST:8779/v1.0/\$(tenant_id)s" \
+                --adminurl "http://$SERVICE_HOST:8779/v1.0/\$(tenant_id)s" \
+                --internalurl "http://$SERVICE_HOST:8779/v1.0/\$(tenant_id)s"
+        fi
+    fi
+}
+
+# stack.sh entry points
+# ---------------------
+
+# cleanup_trove() - Remove residual data files, anything left over from previous
+# runs that a clean run would need to clean up
+function cleanup_trove() {
+    #Clean up dirs
+    rm -fr $TROVE_AUTH_CACHE_DIR/*
+    rm -fr $TROVE_CONF_DIR/*
+}
+
+# configure_troveclient() - Set config files, create data dirs, etc
+function configure_troveclient() {
+    setup_develop $TROVECLIENT_DIR
+}
+
+# configure_trove() - Set config files, create data dirs, etc
+function configure_trove() {
+    setup_develop $TROVE_DIR
+
+    # Create the trove conf dir and cache dirs if they don't exist
+    sudo mkdir -p ${TROVE_CONF_DIR}
+    sudo mkdir -p ${TROVE_AUTH_CACHE_DIR}
+    sudo chown -R $STACK_USER: ${TROVE_CONF_DIR}
+    sudo chown -R $STACK_USER: ${TROVE_AUTH_CACHE_DIR}
+
+    # Copy api-paste file over to the trove conf dir and configure it
+    cp $TROVE_LOCAL_CONF_DIR/api-paste.ini $TROVE_CONF_DIR/api-paste.ini
+    TROVE_API_PASTE_INI=$TROVE_CONF_DIR/api-paste.ini
+    iniset $TROVE_API_PASTE_INI filter:tokenauth auth_host $KEYSTONE_AUTH_HOST
+    iniset $TROVE_API_PASTE_INI filter:tokenauth auth_port $KEYSTONE_AUTH_PORT
+    iniset $TROVE_API_PASTE_INI filter:tokenauth auth_protocol $KEYSTONE_AUTH_PROTOCOL
+    iniset $TROVE_API_PASTE_INI filter:tokenauth admin_tenant_name $SERVICE_TENANT_NAME
+    iniset $TROVE_API_PASTE_INI filter:tokenauth admin_user trove
+    iniset $TROVE_API_PASTE_INI filter:tokenauth admin_password $SERVICE_PASSWORD
+    iniset $TROVE_API_PASTE_INI filter:tokenauth signing_dir $TROVE_AUTH_CACHE_DIR
+
+    # (Re)create trove conf files
+    rm -f $TROVE_CONF_DIR/trove.conf
+    rm -f $TROVE_CONF_DIR/trove-taskmanager.conf
+    iniset $TROVE_CONF_DIR/trove.conf DEFAULT rabbit_password $RABBIT_PASSWORD
+    iniset $TROVE_CONF_DIR/trove.conf DEFAULT sql_connection `database_connection_url trove`
+    iniset $TROVE_CONF_DIR/trove.conf DEFAULT add_addresses True
+
+    iniset $TROVE_LOCAL_CONF_DIR/trove-guestagent.conf.sample DEFAULT rabbit_password $RABBIT_PASSWORD
+    iniset $TROVE_LOCAL_CONF_DIR/trove-guestagent.conf.sample DEFAULT sql_connection `database_connection_url trove`
+    sed -i "s/localhost/$NETWORK_GATEWAY/g" $TROVE_LOCAL_CONF_DIR/trove-guestagent.conf.sample
+
+    # (Re)create trove taskmanager conf file if needed
+    if is_service_enabled tr-tmgr; then
+        iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT rabbit_password $RABBIT_PASSWORD
+        iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT sql_connection `database_connection_url trove`
+        iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT taskmanager_manager trove.taskmanager.manager.Manager
+        iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT nova_proxy_admin_user radmin
+        iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT nova_proxy_admin_tenant_name trove
+        iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT nova_proxy_admin_pass $RADMIN_USER_PASS
+        iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT trove_auth_url $TROVE_AUTH_ENDPOINT
+    fi
+}
+
+# install_troveclient() - Collect source and prepare
+function install_troveclient() {
+    git_clone $TROVECLIENT_REPO $TROVECLIENT_DIR $TROVECLIENT_BRANCH
+}
+
+# install_trove() - Collect source and prepare
+function install_trove() {
+    git_clone $TROVE_REPO $TROVE_DIR $TROVE_BRANCH
+}
+
+# init_trove() - Initializes Trove Database as a Service
+function init_trove() {
+    #(Re)Create trove db
+    recreate_database trove utf8
+
+    #Initialize the trove database
+    $TROVE_DIR/bin/trove-manage db_sync
+}
+
+# start_trove() - Start running processes, including screen
+function start_trove() {
+    screen_it tr-api "cd $TROVE_DIR; bin/trove-api --config-file=$TROVE_CONF_DIR/trove.conf --debug 2>&1"
+    screen_it tr-tmgr "cd $TROVE_DIR; bin/trove-taskmanager --config-file=$TROVE_CONF_DIR/trove-taskmanager.conf --debug 2>&1"
+}
+
+# stop_trove() - Stop running processes
+function stop_trove() {
+    # Kill the trove screen windows
+    for serv in tr-api tr-tmgr; do
+        screen -S $SCREEN_NAME -p $serv -X kill
+    done
+}
+
+# Restore xtrace
+$XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/stack.sh b/stack.sh
index 89e4c24..46c3f44 100755
--- a/stack.sh
+++ b/stack.sh
@@ -2,8 +2,8 @@
 
 # ``stack.sh`` is an opinionated OpenStack developer installation.  It
 # installs and configures various combinations of **Ceilometer**, **Cinder**,
-# **Glance**, **Heat**, **Horizon**, **Keystone**, **Nova**, **Neutron**
-# and **Swift**.
+# **Glance**, **Heat**, **Horizon**, **Keystone**, **Nova**, **Neutron**,
+# **Swift**, and **Trove**
 
 # This script allows you to specify configuration options of what git
 # repositories to use, enabled services, network configuration and various
@@ -203,7 +203,7 @@
     echo "Copying files to $STACK_USER user"
     STACK_DIR="$DEST/${TOP_DIR##*/}"
     cp -r -f -T "$TOP_DIR" "$STACK_DIR"
-    chown -R $STACK_USER "$STACK_DIR"
+    safe_chown -R $STACK_USER "$STACK_DIR"
     cd "$STACK_DIR"
     if [[ "$SHELL_AFTER_RUN" != "no" ]]; then
         exec sudo -u $STACK_USER  bash -l -c "set -e; bash stack.sh; bash"
@@ -236,8 +236,8 @@
 # Create the destination directory and ensure it is writable by the user
 # and read/executable by everybody for daemons (e.g. apache run for horizon)
 sudo mkdir -p $DEST
-sudo chown -R $STACK_USER $DEST
-chmod 0755 $DEST
+safe_chown -R $STACK_USER $DEST
+safe_chmod 0755 $DEST
 
 # a basic test for $DEST path permissions (fatal on error unless skipped)
 check_path_perm_sanity ${DEST}
@@ -258,7 +258,7 @@
 # Destination path for service data
 DATA_DIR=${DATA_DIR:-${DEST}/data}
 sudo mkdir -p $DATA_DIR
-sudo chown -R $STACK_USER $DATA_DIR
+safe_chown -R $STACK_USER $DATA_DIR
 
 
 # Common Configuration
@@ -319,6 +319,7 @@
 source $TOP_DIR/lib/baremetal
 source $TOP_DIR/lib/ldap
 source $TOP_DIR/lib/ironic
+source $TOP_DIR/lib/trove
 
 # Look for Nova hypervisor plugin
 NOVA_PLUGINS=$TOP_DIR/lib/nova_plugins
@@ -517,7 +518,7 @@
         # Set fd 1 and 2 to primary logfile
         exec 1> "${LOGFILE}" 2>&1
         # Set fd 6 to summary logfile and stdout
-        exec 6> >( tee "${SUMFILE}" /dev/fd/3 )
+        exec 6> >( tee "${SUMFILE}" >&3 )
     fi
 
     echo_summary "stack.sh log $LOGFILE"
@@ -720,6 +721,12 @@
     configure_heat
 fi
 
+if is_service_enabled trove; then
+    install_trove
+    install_troveclient
+    cleanup_trove
+fi
+
 if is_service_enabled tls-proxy; then
     configure_CA
     init_CA
@@ -860,6 +867,10 @@
     create_cinder_accounts
     create_neutron_accounts
 
+    if is_service_enabled trove; then
+        create_trove_accounts
+    fi
+
     if is_service_enabled swift || is_service_enabled s-proxy; then
         create_swift_accounts
     fi
@@ -954,7 +965,7 @@
     clean_iptables
     rm -rf ${NOVA_STATE_PATH}/networks
     sudo mkdir -p ${NOVA_STATE_PATH}/networks
-    sudo chown -R ${USER} ${NOVA_STATE_PATH}/networks
+    safe_chown -R ${USER} ${NOVA_STATE_PATH}/networks
     # Force IP forwarding on, just in case
     sudo sysctl -w net.ipv4.ip_forward=1
 fi
@@ -1093,26 +1104,6 @@
             iniset $NOVA_CONF vmware integration_bridge $OVS_BRIDGE
         fi
 
-    # fake
-    # ----
-
-    elif [ "$VIRT_DRIVER" = 'fake' ]; then
-        echo_summary "Using fake Virt driver"
-        iniset $NOVA_CONF DEFAULT compute_driver "nova.virt.fake.FakeDriver"
-        # Disable arbitrary limits
-        iniset $NOVA_CONF DEFAULT quota_instances -1
-        iniset $NOVA_CONF DEFAULT quota_cores -1
-        iniset $NOVA_CONF DEFAULT quota_ram -1
-        iniset $NOVA_CONF DEFAULT quota_floating_ips -1
-        iniset $NOVA_CONF DEFAULT quota_fixed_ips -1
-        iniset $NOVA_CONF DEFAULT quota_metadata_items -1
-        iniset $NOVA_CONF DEFAULT quota_injected_files -1
-        iniset $NOVA_CONF DEFAULT quota_injected_file_path_bytes -1
-        iniset $NOVA_CONF DEFAULT quota_security_groups -1
-        iniset $NOVA_CONF DEFAULT quota_security_group_rules -1
-        iniset $NOVA_CONF DEFAULT quota_key_pairs -1
-        iniset $NOVA_CONF DEFAULT scheduler_default_filters "RetryFilter,AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter"
-
 
     # Default libvirt
     # ---------------
@@ -1236,6 +1227,18 @@
     start_heat
 fi
 
+# Configure and launch the trove service api, and taskmanager
+if is_service_enabled trove; then
+    # Initialize trove
+    echo_summary "Configuring Trove"
+    configure_troveclient
+    configure_trove
+    init_trove
+
+    # Start the trove API and trove taskmgr components
+    echo_summary "Starting Trove"
+    start_trove
+fi
 
 # Create account rc files
 # =======================
diff --git a/stackrc b/stackrc
index f9a977c..3a338d1 100644
--- a/stackrc
+++ b/stackrc
@@ -181,6 +181,13 @@
 SPICE_REPO=${SPICE_REPO:-http://anongit.freedesktop.org/git/spice/spice-html5.git}
 SPICE_BRANCH=${SPICE_BRANCH:-master}
 
+# trove service
+TROVE_REPO=${TROVE_REPO:-${GIT_BASE}/openstack/trove.git}
+TROVE_BRANCH=${TROVE_BRANCH:-master}
+
+# trove client library test
+TROVECLIENT_REPO=${TROVECLIENT_REPO:-${GIT_BASE}/openstack/python-troveclient.git}
+TROVECLIENT_BRANCH=${TROVECLIENT_BRANCH:-master}
 
 # Nova hypervisor configuration.  We default to libvirt with **kvm** but will
 # drop back to **qemu** if we are unable to load the kvm module.  ``stack.sh`` can
diff --git a/tools/docker/install_docker.sh b/tools/docker/install_docker.sh
index d659ad1..289002e 100755
--- a/tools/docker/install_docker.sh
+++ b/tools/docker/install_docker.sh
@@ -38,7 +38,7 @@
 install_package python-software-properties && \
     sudo sh -c "echo deb $DOCKER_APT_REPO docker main > /etc/apt/sources.list.d/docker.list"
 apt_get update
-install_package --force-yes lxc-docker=${DOCKER_PACKAGE_VERSION}
+install_package --force-yes lxc-docker=${DOCKER_PACKAGE_VERSION} socat
 
 # Start the daemon - restart just in case the package ever auto-starts...
 restart_service docker
diff --git a/tools/fixup_stuff.sh b/tools/fixup_stuff.sh
index 371b25f..87922c8 100755
--- a/tools/fixup_stuff.sh
+++ b/tools/fixup_stuff.sh
@@ -34,8 +34,8 @@
 # ---------------
 
 # Pre-install affected packages so we can fix the permissions
-sudo pip install prettytable
-sudo pip install httplib2
+pip_install prettytable
+pip_install httplib2
 
 SITE_DIRS=$(python -c "import site; import os; print os.linesep.join(site.getsitepackages())")
 for dir in $SITE_DIRS; do
diff --git a/tools/install_pip.sh b/tools/install_pip.sh
index cb414a7..fc1c195 100755
--- a/tools/install_pip.sh
+++ b/tools/install_pip.sh
@@ -2,13 +2,11 @@
 
 # **install_pip.sh**
 
-# install_pip.sh [--pip-version <version>] [--use-get-pip] [--setuptools] [--force]
+# install_pip.sh [--pip-version <version>] [--use-get-pip] [--force]
 #
 # Update pip and friends to a known common version
 
 # Assumptions:
-# - currently we try to leave the system setuptools alone, install
-#   the system package if it is not already present
 # - update pip to $INSTALL_PIP_VERSION
 
 # Keep track of the current directory
@@ -35,9 +33,6 @@
             INSTALL_PIP_VERSION="$2"
             shift
             ;;
-        --setuptools)
-            SETUPTOOLS=1
-            ;;
         --use-get-pip)
             USE_GET_PIP=1;
             ;;
@@ -45,7 +40,6 @@
     shift
 done
 
-SETUPTOOLS_EZ_SETUP_URL=https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py
 PIP_GET_PIP_URL=https://raw.github.com/pypa/pip/master/contrib/get-pip.py
 PIP_TAR_URL=https://pypi.python.org/packages/source/p/pip/pip-$INSTALL_PIP_VERSION.tar.gz
 
@@ -55,21 +49,11 @@
 function get_versions() {
     PIP=$(which pip 2>/dev/null || which pip-python 2>/dev/null)
     if [[ -n $PIP ]]; then
-        DISTRIBUTE_VERSION=$($PIP freeze | grep 'distribute==')
-        SETUPTOOLS_VERSION=$($PIP freeze | grep 'setuptools==')
         PIP_VERSION=$($PIP --version | awk '{ print $2}')
-        echo "pip: $PIP_VERSION  setuptools: $SETUPTOOLS_VERSION  distribute: $DISTRIBUTE_VERSION"
+        echo "pip: $PIP_VERSION"
     fi
 }
 
-function setuptools_ez_setup() {
-    if [[ ! -r $FILES/ez_setup.py ]]; then
-        (cd $FILES; \
-         curl -OR $SETUPTOOLS_EZ_SETUP_URL; \
-        )
-    fi
-    sudo python $FILES/ez_setup.py
-}
 
 function install_get_pip() {
     if [[ ! -r $FILES/get-pip.py ]]; then
@@ -92,29 +76,15 @@
 # Show starting versions
 get_versions
 
-# Do setuptools
-if [[ -n "$SETUPTOOLS" ]]; then
-    # We want it from source
-    uninstall_package python-setuptools
-    setuptools_ez_setup
-else
-    # See about installing the distro setuptools
-    if ! python -c "import setuptools"; then
-        install_package python-setuptools
-    fi
-fi
-
 # Do pip
-if [[ -z $PIP || "$PIP_VERSION" != "$INSTALL_PIP_VERSION" || -n $FORCE ]]; then
 
-    # Eradicate any and all system packages
-    uninstall_package python-pip
+# Eradicate any and all system packages
+uninstall_package python-pip
 
-    if [[ -n "$USE_GET_PIP" ]]; then
-        install_get_pip
-    else
-        install_pip_tarball
-    fi
-
-    get_versions
+if [[ -n "$USE_GET_PIP" ]]; then
+    install_get_pip
+else
+    install_pip_tarball
 fi
+
+get_versions
diff --git a/tools/xen/install_os_domU.sh b/tools/xen/install_os_domU.sh
index b49504d..110bbd9 100755
--- a/tools/xen/install_os_domU.sh
+++ b/tools/xen/install_os_domU.sh
@@ -10,6 +10,8 @@
 set -o nounset
 set -o xtrace
 
+export LC_ALL=C
+
 # Abort if localrc is not set
 if [ ! -e ../../localrc ]; then
     echo "You must have a localrc with ALL necessary passwords defined before proceeding."
diff --git a/tools/xen/prepare_guest.sh b/tools/xen/prepare_guest.sh
index 6ec5ffa..05ac86c 100755
--- a/tools/xen/prepare_guest.sh
+++ b/tools/xen/prepare_guest.sh
@@ -56,11 +56,6 @@
 # Give ownership of /opt/stack to stack user
 chown -R $STACK_USER /opt/stack
 
-# Make our ip address hostnames look nice at the command prompt
-echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> /opt/stack/.bashrc
-echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> /root/.bashrc
-echo "export PS1='${debian_chroot:+($debian_chroot)}\\u@\\H:\\w\\$ '" >> /etc/profile
-
 function setup_vimrc {
     if [ ! -e $1 ]; then
         # Simple but usable vimrc
diff --git a/tools/xen/scripts/install-os-vpx.sh b/tools/xen/scripts/install-os-vpx.sh
index c94a593..7469e0c 100755
--- a/tools/xen/scripts/install-os-vpx.sh
+++ b/tools/xen/scripts/install-os-vpx.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 #
 # Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tools/xen/scripts/mkxva b/tools/xen/scripts/mkxva
index a316da2..392c05b 100755
--- a/tools/xen/scripts/mkxva
+++ b/tools/xen/scripts/mkxva
@@ -1,7 +1,7 @@
 #!/bin/bash
 #
 # Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tools/xen/scripts/uninstall-os-vpx.sh b/tools/xen/scripts/uninstall-os-vpx.sh
index 0feaec7..ac26094 100755
--- a/tools/xen/scripts/uninstall-os-vpx.sh
+++ b/tools/xen/scripts/uninstall-os-vpx.sh
@@ -1,7 +1,7 @@
 #!/bin/bash
 #
 # Copyright (c) 2011 Citrix Systems, Inc.
-# Copyright 2011 OpenStack LLC.
+# Copyright 2011 OpenStack Foundation
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/unstack.sh b/unstack.sh
index 38f795b..05d9fb7 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -34,6 +34,7 @@
 source $TOP_DIR/lib/swift
 source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/ironic
+source $TOP_DIR/lib/trove
 
 # Determine what system we are running on.  This provides ``os_VENDOR``,
 # ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME``
@@ -130,4 +131,8 @@
     cleanup_neutron
 fi
 
+if is_service_enabled trove; then
+    cleanup_trove
+fi
+
 cleanup_tmp