Merge "Stop catting tempest.config during tempest setup"
diff --git a/clean.sh b/clean.sh
index e16bdb7..09f08dc 100755
--- a/clean.sh
+++ b/clean.sh
@@ -97,7 +97,7 @@
 fi
 
 # Do the hypervisor cleanup until this can be moved back into lib/nova
-if [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
+if is_service_enabled nova && [[ -r $NOVA_PLUGINS/hypervisor-$VIRT_DRIVER ]]; then
     cleanup_nova_hypervisor
 fi
 
diff --git a/exercises/boot_from_volume.sh b/exercises/boot_from_volume.sh
index ed8ba63..7912046 100755
--- a/exercises/boot_from_volume.sh
+++ b/exercises/boot_from_volume.sh
@@ -30,14 +30,12 @@
 # Import common functions
 source $TOP_DIR/functions
 
+# Import project functions
+source $TOP_DIR/lib/cinder
+
 # Import configuration
 source $TOP_DIR/openrc
 
-# Import neutron functions if needed
-if is_service_enabled neutron; then
-    source $TOP_DIR/lib/neutron
-fi
-
 # Import exercise configuration
 source $TOP_DIR/exerciserc
 
diff --git a/exercises/euca.sh b/exercises/euca.sh
index 51b2644..ad852a4 100755
--- a/exercises/euca.sh
+++ b/exercises/euca.sh
@@ -33,11 +33,6 @@
 # Import EC2 configuration
 source $TOP_DIR/eucarc
 
-# Import neutron functions if needed
-if is_service_enabled neutron; then
-    source $TOP_DIR/lib/neutron
-fi
-
 # Import exercise configuration
 source $TOP_DIR/exerciserc
 
diff --git a/exercises/floating_ips.sh b/exercises/floating_ips.sh
index 4ca90a5..b981aa8 100755
--- a/exercises/floating_ips.sh
+++ b/exercises/floating_ips.sh
@@ -27,14 +27,12 @@
 # Import common functions
 source $TOP_DIR/functions
 
+# Import project functions
+source $TOP_DIR/lib/neutron
+
 # Import configuration
 source $TOP_DIR/openrc
 
-# Import neutron functions if needed
-if is_service_enabled neutron; then
-    source $TOP_DIR/lib/neutron
-fi
-
 # Import exercise configuration
 source $TOP_DIR/exerciserc
 
diff --git a/exercises/volumes.sh b/exercises/volumes.sh
index 21b5d21..33e2458 100755
--- a/exercises/volumes.sh
+++ b/exercises/volumes.sh
@@ -27,14 +27,12 @@
 # Import common functions
 source $TOP_DIR/functions
 
+# Import project functions
+source $TOP_DIR/lib/cinder
+
 # Import configuration
 source $TOP_DIR/openrc
 
-# Import neutron functions if needed
-if is_service_enabled neutron; then
-    source $TOP_DIR/lib/neutron
-fi
-
 # Import exercise configuration
 source $TOP_DIR/exerciserc
 
diff --git a/files/apts/dstat b/files/apts/dstat
new file mode 100644
index 0000000..2b643b8
--- /dev/null
+++ b/files/apts/dstat
@@ -0,0 +1 @@
+dstat
diff --git a/files/rpms-suse/dstat b/files/rpms-suse/dstat
new file mode 100644
index 0000000..2b643b8
--- /dev/null
+++ b/files/rpms-suse/dstat
@@ -0,0 +1 @@
+dstat
diff --git a/files/rpms/dstat b/files/rpms/dstat
new file mode 100644
index 0000000..8a8f8fe
--- /dev/null
+++ b/files/rpms/dstat
@@ -0,0 +1 @@
+dstat
\ No newline at end of file
diff --git a/functions b/functions
index 281b676..dc3278b 100644
--- a/functions
+++ b/functions
@@ -840,6 +840,16 @@
     services=$@
     for service in ${services}; do
         [[ ,${ENABLED_SERVICES}, =~ ,${service}, ]] && return 0
+
+        # Look for top-level 'enabled' function for this service
+        if type is_${service}_enabled >/dev/null 2>&1; then
+            # A function exists for this service, use it
+            is_${service}_enabled
+            return $?
+        fi
+
+        # TODO(dtroyer): Remove these legacy special-cases after the is_XXX_enabled()
+        #                are implemented
         [[ ${service} == n-cell-* && ${ENABLED_SERVICES} =~ "n-cell" ]] && return 0
         [[ ${service} == "nova" && ${ENABLED_SERVICES} =~ "n-" ]] && return 0
         [[ ${service} == "cinder" && ${ENABLED_SERVICES} =~ "c-" ]] && return 0
diff --git a/lib/ceilometer b/lib/ceilometer
index f9c7691..4ca77bb 100644
--- a/lib/ceilometer
+++ b/lib/ceilometer
@@ -59,7 +59,14 @@
 
 # Functions
 # ---------
-#
+
+# Test if any Ceilometer services are enabled
+# is_ceilometer_enabled
+function is_ceilometer_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"ceilometer-" ]] && return 0
+    return 1
+}
+
 # create_ceilometer_accounts() - Set up common required ceilometer accounts
 
 create_ceilometer_accounts() {
diff --git a/lib/cinder b/lib/cinder
index 9f70b2a..e99f893 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -27,6 +27,12 @@
 
 # set up default driver
 CINDER_DRIVER=${CINDER_DRIVER:-default}
+CINDER_PLUGINS=$TOP_DIR/lib/cinder_plugins
+
+# grab plugin config if specified via cinder_driver
+if [[ -r $CINDER_PLUGINS/$CINDER_DRIVER ]]; then
+    source $CINDER_PLUGINS/$CINDER_DRIVER
+fi
 
 # set up default directories
 CINDER_DIR=$DEST/cinder
@@ -85,6 +91,14 @@
 
 # Functions
 # ---------
+
+# Test if any Cinder services are enabled
+# is_cinder_enabled
+function is_cinder_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"c-" ]] && return 0
+    return 1
+}
+
 # _clean_lvm_lv removes all cinder LVM volumes
 #
 # Usage: _clean_lvm_lv $VOLUME_GROUP $VOLUME_NAME_PREFIX
@@ -300,42 +314,8 @@
         setup_colorized_logging $CINDER_CONF DEFAULT "project_id" "user_id"
     fi
 
-    if [ "$CINDER_DRIVER" == "XenAPINFS" ]; then
-        (
-            set -u
-            iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.xenapi.sm.XenAPINFSDriver"
-            iniset $CINDER_CONF DEFAULT xenapi_connection_url "$CINDER_XENAPI_CONNECTION_URL"
-            iniset $CINDER_CONF DEFAULT xenapi_connection_username "$CINDER_XENAPI_CONNECTION_USERNAME"
-            iniset $CINDER_CONF DEFAULT xenapi_connection_password "$CINDER_XENAPI_CONNECTION_PASSWORD"
-            iniset $CINDER_CONF DEFAULT xenapi_nfs_server "$CINDER_XENAPI_NFS_SERVER"
-            iniset $CINDER_CONF DEFAULT xenapi_nfs_serverpath "$CINDER_XENAPI_NFS_SERVERPATH"
-        )
-    elif [ "$CINDER_DRIVER" == "nfs" ]; then
-        iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.nfs.NfsDriver"
-        iniset $CINDER_CONF DEFAULT nfs_shares_config "$CINDER_CONF_DIR/nfs_shares.conf"
-        echo "$CINDER_NFS_SERVERPATH" | sudo tee "$CINDER_CONF_DIR/nfs_shares.conf"
-        sudo chmod 666 $CINDER_CONF_DIR/nfs_shares.conf
-    elif [ "$CINDER_DRIVER" == "sheepdog" ]; then
-        iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.sheepdog.SheepdogDriver"
-    elif [ "$CINDER_DRIVER" == "glusterfs" ]; then
-        # To use glusterfs, set the following in localrc:
-        # CINDER_DRIVER=glusterfs
-        # CINDER_GLUSTERFS_SHARES="127.0.0.1:/vol1;127.0.0.1:/vol2"
-        # Shares are <host>:<volume> and separated by semicolons.
-
-        iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.glusterfs.GlusterfsDriver"
-        iniset $CINDER_CONF DEFAULT glusterfs_shares_config "$CINDER_CONF_DIR/glusterfs_shares"
-        touch $CINDER_CONF_DIR/glusterfs_shares
-        if [ ! -z "$CINDER_GLUSTERFS_SHARES" ]; then
-            CINDER_GLUSTERFS_SHARES=$(echo $CINDER_GLUSTERFS_SHARES | tr ";" "\n")
-            echo "$CINDER_GLUSTERFS_SHARES" > $CINDER_CONF_DIR/glusterfs_shares
-        fi
-    elif [ "$CINDER_DRIVER" == "vsphere" ]; then
-        echo_summary "Using VMware vCenter driver"
-        iniset $CINDER_CONF DEFAULT vmware_host_ip "$VMWAREAPI_IP"
-        iniset $CINDER_CONF DEFAULT vmware_host_username "$VMWAREAPI_USER"
-        iniset $CINDER_CONF DEFAULT vmware_host_password "$VMWAREAPI_PASSWORD"
-        iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.vmware.vmdk.VMwareVcVmdkDriver"
+    if [[ -r $CINDER_PLUGINS/$CINDER_DRIVER ]]; then
+        configure_cinder_driver
     fi
 
     if [[ is_fedora && $DISTRO =~ (rhel6) ]]; then
diff --git a/lib/cinder_plugins/XenAPINFS b/lib/cinder_plugins/XenAPINFS
new file mode 100644
index 0000000..72e1c13
--- /dev/null
+++ b/lib/cinder_plugins/XenAPINFS
@@ -0,0 +1,44 @@
+# lib/cinder_plugins/XenAPINFS
+# Configure the XenAPINFS driver
+
+# Enable with:
+#
+#   CINDER_DRIVER=XenAPINFS
+
+# Dependencies:
+#
+# - ``functions`` file
+# - ``cinder`` configurations
+
+# configure_cinder_driver - make configuration changes, including those to other services
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+
+
+# Entry Points
+# ------------
+
+# configure_cinder_driver - Set config files, create data dirs, etc
+function configure_cinder_driver() {
+    iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.xenapi.sm.XenAPINFSDriver"
+    iniset $CINDER_CONF DEFAULT xenapi_connection_url "$CINDER_XENAPI_CONNECTION_URL"
+    iniset $CINDER_CONF DEFAULT xenapi_connection_username "$CINDER_XENAPI_CONNECTION_USERNAME"
+    iniset $CINDER_CONF DEFAULT xenapi_connection_password "$CINDER_XENAPI_CONNECTION_PASSWORD"
+    iniset $CINDER_CONF DEFAULT xenapi_nfs_server "$CINDER_XENAPI_NFS_SERVER"
+    iniset $CINDER_CONF DEFAULT xenapi_nfs_serverpath "$CINDER_XENAPI_NFS_SERVERPATH"
+}
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/cinder_plugins/glusterfs b/lib/cinder_plugins/glusterfs
new file mode 100644
index 0000000..a0c5ae8
--- /dev/null
+++ b/lib/cinder_plugins/glusterfs
@@ -0,0 +1,50 @@
+# lib/cinder_plugins/glusterfs
+# Configure the glusterfs driver
+
+# Enable with:
+#
+#   CINDER_DRIVER=glusterfs
+
+# Dependencies:
+#
+# - ``functions`` file
+# - ``cinder`` configurations
+
+# configure_cinder_driver - make configuration changes, including those to other services
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+
+
+# Entry Points
+# ------------
+
+# configure_cinder_driver - Set config files, create data dirs, etc
+function configure_cinder_driver() {
+    # To use glusterfs, set the following in localrc:
+    # CINDER_DRIVER=glusterfs
+    # CINDER_GLUSTERFS_SHARES="127.0.0.1:/vol1;127.0.0.1:/vol2"
+    # Shares are <host>:<volume> and separated by semicolons.
+
+    iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.glusterfs.GlusterfsDriver"
+    iniset $CINDER_CONF DEFAULT glusterfs_shares_config "$CINDER_CONF_DIR/glusterfs_shares"
+    touch $CINDER_CONF_DIR/glusterfs_shares
+    if [ ! -z "$CINDER_GLUSTERFS_SHARES" ]; then
+        CINDER_GLUSTERFS_SHARES=$(echo $CINDER_GLUSTERFS_SHARES | tr ";" "\n")
+        echo "$CINDER_GLUSTERFS_SHARES" > $CINDER_CONF_DIR/glusterfs_shares
+    fi
+}
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/cinder_plugins/nfs b/lib/cinder_plugins/nfs
new file mode 100644
index 0000000..ea2c9ce
--- /dev/null
+++ b/lib/cinder_plugins/nfs
@@ -0,0 +1,42 @@
+# lib/cinder_plugins/nfs
+# Configure the nfs driver
+
+# Enable with:
+#
+#   CINDER_DRIVER=nfs
+
+# Dependencies:
+#
+# - ``functions`` file
+# - ``cinder`` configurations
+
+# configure_cinder_driver - make configuration changes, including those to other services
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+
+
+# Entry Points
+# ------------
+
+# configure_cinder_driver - Set config files, create data dirs, etc
+function configure_cinder_driver() {
+    iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.nfs.NfsDriver"
+    iniset $CINDER_CONF DEFAULT nfs_shares_config "$CINDER_CONF_DIR/nfs_shares.conf"
+    echo "$CINDER_NFS_SERVERPATH" | sudo tee "$CINDER_CONF_DIR/nfs_shares.conf"
+    sudo chmod 660 $CINDER_CONF_DIR/nfs_shares.conf
+}
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/cinder_plugins/sheepdog b/lib/cinder_plugins/sheepdog
new file mode 100644
index 0000000..4435932
--- /dev/null
+++ b/lib/cinder_plugins/sheepdog
@@ -0,0 +1,39 @@
+# lib/cinder_plugins/sheepdog
+# Configure the sheepdog driver
+
+# Enable with:
+#
+#   CINDER_DRIVER=sheepdog
+
+# Dependencies:
+#
+# - ``functions`` file
+# - ``cinder`` configurations
+
+# configure_cinder_driver - make configuration changes, including those to other services
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+
+
+# Entry Points
+# ------------
+
+# configure_cinder_driver - Set config files, create data dirs, etc
+function configure_cinder_driver() {
+    iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.sheepdog.SheepdogDriver"
+}
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/cinder_plugins/solidfire b/lib/cinder_plugins/solidfire
new file mode 100644
index 0000000..47c113e
--- /dev/null
+++ b/lib/cinder_plugins/solidfire
@@ -0,0 +1,48 @@
+# lib/cinder_plugins/solidfire
+# Configure the solidfire driver
+
+# Enable with:
+#
+#   CINDER_DRIVER=solidfire
+
+# Dependencies:
+#
+# - ``functions`` file
+# - ``cinder`` configurations
+
+# configure_cinder_driver - make configuration changes, including those to other services
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+
+
+# Entry Points
+# ------------
+
+# configure_cinder_driver - Set config files, create data dirs, etc
+function configure_cinder_driver() {
+    # To use solidfire, set the following in localrc:
+    # CINDER_DRIVER=solidfire
+    # SAN_IP=<mvip>
+    # SAN_LOGIN=<cluster-admin-account>
+    # SAN_PASSWORD=<cluster-admin-password>
+
+    iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.solidfire.SolidFireDriver"
+    iniset $CINDER_CONF DEFAULT san_ip $SAN_IP
+    iniset $CINDER_CONF DEFAULT san_login $SAN_LOGIN
+    iniset $CINDER_CONF DEFAULT san_password $SAN_PASSWORD
+}
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/cinder_plugins/vsphere b/lib/cinder_plugins/vsphere
new file mode 100644
index 0000000..c8cab6a
--- /dev/null
+++ b/lib/cinder_plugins/vsphere
@@ -0,0 +1,42 @@
+# lib/cinder_plugins/vsphere
+# Configure the vsphere driver
+
+# Enable with:
+#
+#   CINDER_DRIVER=vsphere
+
+# Dependencies:
+#
+# - ``functions`` file
+# - ``cinder`` configurations
+
+# configure_cinder_driver - make configuration changes, including those to other services
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+
+
+# Entry Points
+# ------------
+
+# configure_cinder_driver - Set config files, create data dirs, etc
+function configure_cinder_driver() {
+    iniset $CINDER_CONF DEFAULT vmware_host_ip "$VMWAREAPI_IP"
+    iniset $CINDER_CONF DEFAULT vmware_host_username "$VMWAREAPI_USER"
+    iniset $CINDER_CONF DEFAULT vmware_host_password "$VMWAREAPI_PASSWORD"
+    iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.vmware.vmdk.VMwareVcVmdkDriver"
+}
+
+# Restore xtrace
+$MY_XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/lib/glance b/lib/glance
index a5cb360..1ebeeb3 100644
--- a/lib/glance
+++ b/lib/glance
@@ -59,6 +59,13 @@
 # Functions
 # ---------
 
+# Test if any Glance services are enabled
+# is_glance_enabled
+function is_glance_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"g-" ]] && return 0
+    return 1
+}
+
 # cleanup_glance() - Remove residual data files, anything left over from previous
 # runs that a clean run would need to clean up
 function cleanup_glance() {
diff --git a/lib/ironic b/lib/ironic
index 0b9df57..3c0e3cb 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -112,11 +112,6 @@
     iniset $IRONIC_CONF_FILE keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
     iniset $IRONIC_CONF_FILE keystone_authtoken admin_user ironic
     iniset $IRONIC_CONF_FILE keystone_authtoken admin_password $SERVICE_PASSWORD
-    if is_service_enabled qpid; then
-        iniset $IRONIC_CONF_FILE DEFAULT notifier_strategy qpid
-    elif [ -n "$RABBIT_HOST" ] &&  [ -n "$RABBIT_PASSWORD" ]; then
-        iniset $IRONIC_CONF_FILE DEFAULT notifier_strategy rabbit
-    fi
     iniset_rpc_backend ironic $IRONIC_CONF_FILE DEFAULT
     iniset $IRONIC_CONF_FILE keystone_authtoken signing_dir $IRONIC_AUTH_CACHE_DIR/api
 
diff --git a/lib/marconi b/lib/marconi
index 1eaebbd..0aaff1b 100644
--- a/lib/marconi
+++ b/lib/marconi
@@ -52,12 +52,19 @@
 MARCONICLIENT_BRANCH=${MARCONICLIENT_BRANCH:-master}
 
 # Tell Tempest this project is present
-TEMPEST_SERVICES+=,marconi
+TEMPEST_SERVICES+=,marconi-server
 
 
 # Functions
 # ---------
 
+# Test if any Marconi services are enabled
+# is_marconi_enabled
+function is_marconi_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"marconi-" ]] && return 0
+    return 1
+}
+
 # cleanup_marconi() - Remove residual data files, anything left over from previous
 # runs that a clean run would need to clean up
 function cleanup_marconi() {
diff --git a/lib/neutron b/lib/neutron
index 81db2a7..5bd38bc 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -244,6 +244,13 @@
 # Functions
 # ---------
 
+# Test if any Neutron services are enabled
+# is_neutron_enabled
+function is_neutron_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"q-" ]] && return 0
+    return 1
+}
+
 # configure_neutron()
 # Set common config for all neutron server and agents.
 function configure_neutron() {
diff --git a/lib/neutron_plugins/embrane b/lib/neutron_plugins/embrane
new file mode 100644
index 0000000..4206a20
--- /dev/null
+++ b/lib/neutron_plugins/embrane
@@ -0,0 +1,40 @@
+# Neutron Embrane plugin
+# ---------------------------
+
+# Save trace setting
+MY_XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+source $TOP_DIR/lib/neutron_plugins/openvswitch
+
+save_function() {
+    local ORIG_FUNC=$(declare -f $1)
+    local NEW_FUNC="$2${ORIG_FUNC#$1}"
+    eval "$NEW_FUNC"
+}
+
+save_function neutron_plugin_configure_service _neutron_plugin_configure_service
+
+function neutron_plugin_configure_common() {
+    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/embrane
+    Q_PLUGIN_CONF_FILENAME=heleos_conf.ini
+    Q_DB_NAME="ovs_neutron"
+    Q_PLUGIN_CLASS="neutron.plugins.embrane.plugins.embrane_ovs_plugin.EmbraneOvsPlugin"
+}
+
+function neutron_plugin_configure_service() {
+    _neutron_plugin_configure_service
+    iniset /$Q_PLUGIN_CONF_FILE heleos esm_mgmt $HELEOS_ESM_MGMT
+    iniset /$Q_PLUGIN_CONF_FILE heleos admin_username $HELEOS_ADMIN_USERNAME
+    iniset /$Q_PLUGIN_CONF_FILE heleos admin_password $HELEOS_ADMIN_PASSWORD
+    iniset /$Q_PLUGIN_CONF_FILE heleos router_image $HELEOS_ROUTER_IMAGE
+    iniset /$Q_PLUGIN_CONF_FILE heleos mgmt_id $HELEOS_MGMT_ID
+    iniset /$Q_PLUGIN_CONF_FILE heleos inband_id $HELEOS_INBAND_ID
+    iniset /$Q_PLUGIN_CONF_FILE heleos oob_id $HELEOS_OOB_ID
+    iniset /$Q_PLUGIN_CONF_FILE heleos dummy_utif_id $HELEOS_DUMMY_UTIF_ID
+    iniset /$Q_PLUGIN_CONF_FILE heleos resource_pool_id $HELEOS_RESOURCE_POOL_ID
+    iniset /$Q_PLUGIN_CONF_FILE heleos async_requests $HELEOS_ASYNC_REQUESTS
+}
+
+# Restore xtrace
+$MY_XTRACE
\ No newline at end of file
diff --git a/lib/nova b/lib/nova
index 5106eaa..eaaaa62 100644
--- a/lib/nova
+++ b/lib/nova
@@ -129,6 +129,20 @@
 # Functions
 # ---------
 
+# Test if any Nova services are enabled
+# is_nova_enabled
+function is_nova_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"n-" ]] && return 0
+    return 1
+}
+
+# Test if any Nova Cell services are enabled
+# is_nova_enabled
+function is_n-cell_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"n-cell-" ]] && return 0
+    return 1
+}
+
 # Helper to clean iptables rules
 function clean_iptables() {
     # Delete rules
@@ -389,6 +403,10 @@
     fi
 
     if is_service_enabled n-api; then
+        if is_service_enabled n-api-meta; then
+            # If running n-api-meta as a separate service
+            NOVA_ENABLED_APIS=$(echo $NOVA_ENABLED_APIS | sed "s/,metadata//")
+        fi
         iniset $NOVA_CONF DEFAULT enabled_apis "$NOVA_ENABLED_APIS"
         if is_service_enabled tls-proxy; then
             # Set the service port for a proxy to take the original
diff --git a/lib/nova_plugins/hypervisor-docker b/lib/nova_plugins/hypervisor-docker
index bb934b8..cdd9317 100644
--- a/lib/nova_plugins/hypervisor-docker
+++ b/lib/nova_plugins/hypervisor-docker
@@ -31,8 +31,8 @@
 DOCKER_PID_FILE=/var/run/docker.pid
 DOCKER_REGISTRY_PORT=${DOCKER_REGISTRY_PORT:-5042}
 
-DOCKER_IMAGE=${DOCKER_IMAGE:-busybox:latest}
-DOCKER_IMAGE_NAME=busybox
+DOCKER_IMAGE=${DOCKER_IMAGE:-cirros:latest}
+DOCKER_IMAGE_NAME=cirros
 DOCKER_REGISTRY_IMAGE=${DOCKER_REGISTRY_IMAGE:-registry:latest}
 DOCKER_REGISTRY_IMAGE_NAME=registry
 DOCKER_REPOSITORY_NAME=${SERVICE_HOST}:${DOCKER_REGISTRY_PORT}/${DOCKER_IMAGE_NAME}
diff --git a/lib/swift b/lib/swift
index 28ca8a8..be25c81 100644
--- a/lib/swift
+++ b/lib/swift
@@ -118,6 +118,13 @@
 # Functions
 # ---------
 
+# Test if any Swift services are enabled
+# is_swift_enabled
+function is_swift_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"s-" ]] && return 0
+    return 1
+}
+
 # cleanup_swift() - Remove residual data files
 function cleanup_swift() {
     rm -f ${SWIFT_CONF_DIR}{*.builder,*.ring.gz,backups/*.builder,backups/*.ring.gz}
@@ -341,7 +348,7 @@
 # NOTE(chmou): s3token middleware is not updated yet to use only
 # username and password.
 [filter:s3token]
-paste.filter_factory = keystone.middleware.s3_token:filter_factory
+paste.filter_factory = keystoneclient.middleware.s3_token:filter_factory
 auth_port = ${KEYSTONE_AUTH_PORT}
 auth_host = ${KEYSTONE_AUTH_HOST}
 auth_protocol = ${KEYSTONE_AUTH_PROTOCOL}
@@ -513,6 +520,11 @@
 # swifttenanttest2   swiftusertest2     admin
 
 function create_swift_accounts() {
+    # Defines specific passwords used by tools/create_userrc.sh
+    SWIFTUSERTEST1_PASSWORD=testing
+    SWIFTUSERTEST2_PASSWORD=testing2
+    SWIFTUSERTEST3_PASSWORD=testing3
+
     KEYSTONE_CATALOG_BACKEND=${KEYSTONE_CATALOG_BACKEND:-sql}
 
     SERVICE_TENANT=$(keystone tenant-list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
@@ -535,17 +547,17 @@
 
     SWIFT_TENANT_TEST1=$(keystone tenant-create --name=swifttenanttest1 | grep " id " | get_field 2)
     die_if_not_set $LINENO SWIFT_TENANT_TEST1 "Failure creating SWIFT_TENANT_TEST1"
-    SWIFT_USER_TEST1=$(keystone user-create --name=swiftusertest1 --pass=testing --email=test@example.com | grep " id " | get_field 2)
+    SWIFT_USER_TEST1=$(keystone user-create --name=swiftusertest1 --pass=$SWIFTUSERTEST1_PASSWORD --email=test@example.com | grep " id " | get_field 2)
     die_if_not_set $LINENO SWIFT_USER_TEST1 "Failure creating SWIFT_USER_TEST1"
     keystone user-role-add --user-id $SWIFT_USER_TEST1 --role-id $ADMIN_ROLE --tenant-id $SWIFT_TENANT_TEST1
 
-    SWIFT_USER_TEST3=$(keystone user-create --name=swiftusertest3 --pass=testing3 --email=test3@example.com | grep " id " | get_field 2)
+    SWIFT_USER_TEST3=$(keystone user-create --name=swiftusertest3 --pass=$SWIFTUSERTEST3_PASSWORD --email=test3@example.com | grep " id " | get_field 2)
     die_if_not_set $LINENO SWIFT_USER_TEST3 "Failure creating SWIFT_USER_TEST3"
     keystone user-role-add --user-id $SWIFT_USER_TEST3 --role-id $ANOTHER_ROLE --tenant-id $SWIFT_TENANT_TEST1
 
     SWIFT_TENANT_TEST2=$(keystone tenant-create --name=swifttenanttest2 | grep " id " | get_field 2)
     die_if_not_set $LINENO SWIFT_TENANT_TEST2 "Failure creating SWIFT_TENANT_TEST2"
-    SWIFT_USER_TEST2=$(keystone user-create --name=swiftusertest2 --pass=testing2 --email=test2@example.com | grep " id " | get_field 2)
+    SWIFT_USER_TEST2=$(keystone user-create --name=swiftusertest2 --pass=$SWIFTUSERTEST2_PASSWORD --email=test2@example.com | grep " id " | get_field 2)
     die_if_not_set $LINENO SWIFT_USER_TEST2 "Failure creating SWIFT_USER_TEST2"
     keystone user-role-add --user-id $SWIFT_USER_TEST2 --role-id $ADMIN_ROLE --tenant-id $SWIFT_TENANT_TEST2
 }
diff --git a/lib/template b/lib/template
index 629e110..b8e7c4d 100644
--- a/lib/template
+++ b/lib/template
@@ -10,6 +10,7 @@
 
 # ``stack.sh`` calls the entry points in this order:
 #
+# - is_XXXX_enabled
 # - install_XXXX
 # - configure_XXXX
 # - init_XXXX
@@ -35,6 +36,13 @@
 # Entry Points
 # ------------
 
+# Test if any XXXX services are enabled
+# is_XXXX_enabled
+function is_XXXX_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"XX-" ]] && return 0
+    return 1
+}
+
 # cleanup_XXXX() - Remove residual data files, anything left over from previous
 # runs that a clean run would need to clean up
 function cleanup_XXXX() {
diff --git a/stack.sh b/stack.sh
index 1a1460d..1dc4b74 100755
--- a/stack.sh
+++ b/stack.sh
@@ -298,6 +298,8 @@
 SYSSTAT_FILE=${SYSSTAT_FILE:-"sysstat.dat"}
 SYSSTAT_INTERVAL=${SYSSTAT_INTERVAL:-"1"}
 
+DSTAT_FILE=${DSTAT_FILE:-"dstat.txt"}
+
 PIDSTAT_FILE=${PIDSTAT_FILE:-"pidstat.txt"}
 PIDSTAT_INTERVAL=${PIDSTAT_INTERVAL:-"5"}
 
@@ -362,7 +364,11 @@
     var=$1; msg=$2
     pw=${!var}
 
-    localrc=$TOP_DIR/localrc
+    if [[ -f $RC_DIR/localrc ]]; then
+        localrc=$TOP_DIR/localrc
+    else
+        localrc=$TOP_DIR/.localrc.auto
+    fi
 
     # If the password is not defined yet, proceed to prompt user for a password.
     if [ ! $pw ]; then
@@ -875,6 +881,16 @@
     fi
 fi
 
+if is_service_enabled dstat; then
+    # Per-process stats
+    DSTAT_OPTS="-tcndylp --top-cpu-adv"
+    if [[ -n ${SCREEN_LOGDIR} ]]; then
+        screen_it dstat "cd $TOP_DIR; dstat $DSTAT_OPTS | tee $SCREEN_LOGDIR/$DSTAT_FILE"
+    else
+        screen_it dstat "dstat $DSTAT_OPTS"
+    fi
+fi
+
 if is_service_enabled pidstat; then
     # Per-process stats
     PIDSTAT_OPTS="-l -p ALL -T ALL"
@@ -1081,7 +1097,7 @@
 fi
 
 # Launch the Glance services
-if is_service_enabled g-api g-reg; then
+if is_service_enabled glance; then
     echo_summary "Starting Glance"
     start_glance
 fi
@@ -1165,7 +1181,7 @@
 
 # Configure and launch heat engine, api and metadata
 if is_service_enabled heat; then
-    # Initialize heat, including replacing nova flavors
+    # Initialize heat
     echo_summary "Configuring Heat"
     init_heat
     echo_summary "Starting Heat"
@@ -1334,11 +1350,6 @@
     echo "Horizon is now available at http://$SERVICE_HOST/"
 fi
 
-# Warn that the default flavors have been changed by Heat
-if is_service_enabled heat; then
-    echo "Heat has replaced the default flavors. View by running: nova flavor-list"
-fi
-
 # If Keystone is present you can point ``nova`` cli to this server
 if is_service_enabled key; then
     echo "Keystone is serving at $KEYSTONE_AUTH_PROTOCOL://$SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0/"
diff --git a/stackrc b/stackrc
index 7eed60c..9166a17 100644
--- a/stackrc
+++ b/stackrc
@@ -35,7 +35,7 @@
 #  enable_service neutron
 #  # Optional, to enable tempest configuration as part of devstack
 #  enable_service tempest
-ENABLED_SERVICES=g-api,g-reg,key,n-api,n-crt,n-obj,n-cpu,n-net,n-cond,cinder,c-sch,c-api,c-vol,n-sch,n-novnc,n-xvnc,n-cauth,horizon,rabbit,tempest,mysql
+ENABLED_SERVICES=g-api,g-reg,key,n-api,n-crt,n-obj,n-cpu,n-net,n-cond,c-sch,c-api,c-vol,n-sch,n-novnc,n-xvnc,n-cauth,horizon,rabbit,tempest,mysql
 
 # Tell Tempest which services are available.  The default is set here as
 # Tempest falls late in the configuration sequence.  This differs from
diff --git a/tools/build_tempest.sh b/tools/build_tempest.sh
deleted file mode 100755
index 6c527f5..0000000
--- a/tools/build_tempest.sh
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/env bash
-#
-# **build_tempest.sh**
-
-# Checkout and prepare a Tempest repo: git://git.openstack.org/openstack/tempest.git
-
-function usage {
-    echo "$0 - Check out and prepare a Tempest repo"
-    echo ""
-    echo "Usage: $0"
-    exit 1
-}
-
-if [ "$1" = "-h" ]; then
-    usage
-fi
-
-# Clean up any resources that may be in use
-cleanup() {
-    set +o errexit
-
-    # Kill ourselves to signal any calling process
-    trap 2; kill -2 $$
-}
-
-trap cleanup SIGHUP SIGINT SIGTERM SIGQUIT EXIT
-
-# Keep track of the current directory
-TOOLS_DIR=$(cd $(dirname "$0") && pwd)
-TOP_DIR=$(cd $TOOLS_DIR/..; pwd)
-
-# Import common functions
-. $TOP_DIR/functions
-
-# Abort if localrc is not set
-if [ ! -e $TOP_DIR/localrc ]; then
-    echo "You must have a localrc with ALL necessary passwords and configuration defined before proceeding."
-    echo "See stack.sh for required passwords."
-    exit 1
-fi
-
-# Source params
-source ./stackrc
-
-# Where Openstack code lives
-DEST=${DEST:-/opt/stack}
-
-TEMPEST_DIR=$DEST/tempest
-
-# Install tests and prerequisites
-git_clone $TEMPEST_REPO $TEMPEST_DIR $TEMPEST_BRANCH
-
-trap - SIGHUP SIGINT SIGTERM SIGQUIT EXIT
diff --git a/tools/create_userrc.sh b/tools/create_userrc.sh
index e2d855c..d9c93cc 100755
--- a/tools/create_userrc.sh
+++ b/tools/create_userrc.sh
@@ -253,6 +253,14 @@
             if [ $MODE = one -a "$user_name" != "$USER_NAME" ]; then
                 continue;
             fi
+
+            # Checks for a specific password defined for an user.
+            # Example for an username johndoe:
+            #                     JOHNDOE_PASSWORD=1234
+            eval SPECIFIC_UPASSWORD="\$${USER_NAME^^}_PASSWORD"
+            if [ -n "$SPECIFIC_UPASSWORD" ]; then
+                USER_PASS=$SPECIFIC_UPASSWORD
+            fi
             add_entry "$user_id" "$user_name" "$tenant_id" "$tenant_name" "$USER_PASS"
         done
     done
diff --git a/tools/docker/install_docker.sh b/tools/docker/install_docker.sh
index 4fa2386..b9e1b24 100755
--- a/tools/docker/install_docker.sh
+++ b/tools/docker/install_docker.sh
@@ -60,5 +60,5 @@
 docker tag $DOCKER_IMAGE $DOCKER_IMAGE_NAME
 
 # Get docker-registry image
-docker pull $REGISTRY_IMAGE
-docker tag $REGISTRY_IMAGE $REGISTRY_IMAGE_NAME
+docker pull $DOCKER_REGISTRY_IMAGE
+docker tag $DOCKER_REGISTRY_IMAGE $DOCKER_REGISTRY_IMAGE_NAME
diff --git a/tools/xen/build_xva.sh b/tools/xen/build_xva.sh
index 958102b..fbbfd6f 100755
--- a/tools/xen/build_xva.sh
+++ b/tools/xen/build_xva.sh
@@ -21,9 +21,19 @@
 # This directory
 TOP_DIR=$(cd $(dirname "$0") && pwd)
 
+# Source lower level functions
+. $TOP_DIR/../../functions
+
 # Include onexit commands
 . $TOP_DIR/scripts/on_exit.sh
 
+# xapi functions
+. $TOP_DIR/functions
+
+# Determine what system we are running on.
+# Might not be XenServer if we're using xenserver-core
+GetDistro
+
 # Source params - override xenrc params in your localrc to suite your taste
 source xenrc
 
diff --git a/tools/xen/prepare_guest_template.sh b/tools/xen/prepare_guest_template.sh
index 546ac99..4fa70d3 100755
--- a/tools/xen/prepare_guest_template.sh
+++ b/tools/xen/prepare_guest_template.sh
@@ -22,9 +22,19 @@
 # This directory
 TOP_DIR=$(cd $(dirname "$0") && pwd)
 
+# Source lower level functions
+. $TOP_DIR/../../functions
+
 # Include onexit commands
 . $TOP_DIR/scripts/on_exit.sh
 
+# xapi functions
+. $TOP_DIR/functions
+
+# Determine what system we are running on.
+# Might not be XenServer if we're using xenserver-core
+GetDistro
+
 # Source params - override xenrc params in your localrc to suite your taste
 source xenrc
 
diff --git a/tools/xen/xenrc b/tools/xen/xenrc
index b355a10..278bb9b 100644
--- a/tools/xen/xenrc
+++ b/tools/xen/xenrc
@@ -91,4 +91,7 @@
 # Set the size to 0 to avoid creation of additional disk.
 XEN_XVDB_SIZE_GB=0
 
+restore_nounset=`set +o | grep nounset`
+set +u
 source ../../stackrc
+$restore_nounset
diff --git a/unstack.sh b/unstack.sh
index ea9c27d..6351fe0 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -103,7 +103,7 @@
     stop_nova
 fi
 
-if is_service_enabled g-api g-reg; then
+if is_service_enabled glance; then
     stop_glance
 fi