Merge "enable multiple collector workers"
diff --git a/docs/source/index.html b/docs/source/index.html
index 1a31df1..dada57d 100644
--- a/docs/source/index.html
+++ b/docs/source/index.html
@@ -287,8 +287,8 @@
                 <td><a href="lib/ldap.html" class="btn btn-small btn-primary table-action">Read &raquo;</a></td>
               </tr>
               <tr>
-                <td>lib/marconi</td>
-                <td><a href="lib/marconi.html" class="btn btn-small btn-primary table-action">Read &raquo;</a></td>
+                <td>lib/zaqar</td>
+                <td><a href="lib/zaqar.html" class="btn btn-small btn-primary table-action">Read &raquo;</a></td>
               </tr>
               <tr>
                 <td>lib/neutron</td>
@@ -351,8 +351,8 @@
                 <td><a href="extras.d/50-ironic.html" class="btn btn-small btn-primary table-action">Read &raquo;</a></td>
               </tr>
               <tr>
-                <td>extras.d/70-marconi.sh</td>
-                <td><a href="extras.d/70-marconi.html" class="btn btn-small btn-primary table-action">Read &raquo;</a></td>
+                <td>extras.d/70-zaqar.sh</td>
+                <td><a href="extras.d/70-zaqar.html" class="btn btn-small btn-primary table-action">Read &raquo;</a></td>
               </tr>
               <tr>
                 <td>extras.d/70-sahara.sh</td>
@@ -517,9 +517,6 @@
                 <td>exercises/horizon.sh</td>
                 <td><a href="exercises/horizon.sh.html" class="btn btn-small btn-primary table-action">Read &raquo;</a></td>
               </tr>
-                <td>exercises/marconi.sh</td>
-                <td><a href="exercises/marconi.sh.html" class="btn btn-small btn-primary table-action">Read &raquo;</a></td>
-              </tr>
               <tr>
                 <td>exercises/neutron-adv-test.sh</td>
                 <td><a href="exercises/neutron-adv-test.sh.html" class="btn btn-small btn-primary table-action">Read &raquo;</a></td>
@@ -545,6 +542,10 @@
                 <td>exercises/volumes.sh</td>
                 <td><a href="exercises/volumes.sh.html" class="btn btn-small btn-primary table-action">Read &raquo;</a></td>
               </tr>
+              <tr>
+                <td>exercises/zaqar.sh</td>
+                <td><a href="exercises/zaqar.sh.html" class="btn btn-small btn-primary table-action">Read &raquo;</a></td>
+              </tr>
             </tbody>
           </table>
 
diff --git a/exercises/marconi.sh b/exercises/zaqar.sh
similarity index 86%
rename from exercises/marconi.sh
rename to exercises/zaqar.sh
index 9d83a99..6996f34 100755
--- a/exercises/marconi.sh
+++ b/exercises/zaqar.sh
@@ -1,8 +1,8 @@
 #!/usr/bin/env bash
 
-# **marconi.sh**
+# **zaqar.sh**
 
-# Sanity check that Marconi started if enabled
+# Sanity check that Zaqar started if enabled
 
 echo "*********************************************************************"
 echo "Begin DevStack Exercise: $0"
@@ -33,9 +33,9 @@
 # Import exercise configuration
 source $TOP_DIR/exerciserc
 
-is_service_enabled marconi-server || exit 55
+is_service_enabled zaqar-server || exit 55
 
-curl http://$SERVICE_HOST:8888/v1/ 2>/dev/null | grep -q 'queue_name' || die $LINENO "Marconi API not functioning!"
+curl http://$SERVICE_HOST:8888/v1/ 2>/dev/null | grep -q 'queue_name' || die $LINENO "Zaqar API not functioning!"
 
 set +o xtrace
 echo "*********************************************************************"
diff --git a/extras.d/70-marconi.sh b/extras.d/70-marconi.sh
deleted file mode 100644
index a96a4c5..0000000
--- a/extras.d/70-marconi.sh
+++ /dev/null
@@ -1,29 +0,0 @@
-# marconi.sh - Devstack extras script to install Marconi
-
-if is_service_enabled marconi-server; then
-    if [[ "$1" == "source" ]]; then
-        # Initial source
-        source $TOP_DIR/lib/marconi
-    elif [[ "$1" == "stack" && "$2" == "install" ]]; then
-        echo_summary "Installing Marconi"
-        install_marconiclient
-        install_marconi
-    elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
-        echo_summary "Configuring Marconi"
-        configure_marconi
-        configure_marconiclient
-
-        if is_service_enabled key; then
-            create_marconi_accounts
-        fi
-
-    elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
-        echo_summary "Initializing Marconi"
-        init_marconi
-        start_marconi
-    fi
-
-    if [[ "$1" == "unstack" ]]; then
-        stop_marconi
-    fi
-fi
diff --git a/extras.d/70-zaqar.sh b/extras.d/70-zaqar.sh
new file mode 100644
index 0000000..63c4fd5
--- /dev/null
+++ b/extras.d/70-zaqar.sh
@@ -0,0 +1,29 @@
+# zaqar.sh - Devstack extras script to install Zaqar
+
+if is_service_enabled zaqar-server; then
+    if [[ "$1" == "source" ]]; then
+        # Initial source
+        source $TOP_DIR/lib/zaqar
+    elif [[ "$1" == "stack" && "$2" == "install" ]]; then
+        echo_summary "Installing Zaqar"
+        install_zaqarclient
+        install_zaqar
+    elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
+        echo_summary "Configuring Zaqar"
+        configure_zaqar
+        configure_zaqarclient
+
+        if is_service_enabled key; then
+            create_zaqar_accounts
+        fi
+
+    elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
+        echo_summary "Initializing Zaqar"
+        init_zaqar
+        start_zaqar
+    fi
+
+    if [[ "$1" == "unstack" ]]; then
+        stop_zaqar
+    fi
+fi
diff --git a/files/apache-horizon.template b/files/apache-horizon.template
index af880c4..c1dd693 100644
--- a/files/apache-horizon.template
+++ b/files/apache-horizon.template
@@ -1,6 +1,6 @@
 <VirtualHost *:80>
     WSGIScriptAlias / %HORIZON_DIR%/openstack_dashboard/wsgi/django.wsgi
-    WSGIDaemonProcess horizon user=%USER% group=%GROUP% processes=3 threads=10 home=%HORIZON_DIR%
+    WSGIDaemonProcess horizon user=%USER% group=%GROUP% processes=3 threads=10 home=%HORIZON_DIR% display-name=%{GROUP}
     WSGIApplicationGroup %{GLOBAL}
 
     SetEnv APACHE_RUN_USER %USER%
diff --git a/files/apache-keystone.template b/files/apache-keystone.template
index 805e7b8..fc8731c 100644
--- a/files/apache-keystone.template
+++ b/files/apache-keystone.template
@@ -2,7 +2,7 @@
 Listen %ADMINPORT%
 
 <VirtualHost *:%PUBLICPORT%>
-    WSGIDaemonProcess keystone-public processes=5 threads=1 user=%USER%
+    WSGIDaemonProcess keystone-public processes=5 threads=1 user=%USER% display-name=%{GROUP}
     WSGIProcessGroup keystone-public
     WSGIScriptAlias / %PUBLICWSGI%
     WSGIApplicationGroup %{GLOBAL}
@@ -12,7 +12,7 @@
 </VirtualHost>
 
 <VirtualHost *:%ADMINPORT%>
-    WSGIDaemonProcess keystone-admin processes=5 threads=1 user=%USER%
+    WSGIDaemonProcess keystone-admin processes=5 threads=1 user=%USER% display-name=%{GROUP}
     WSGIProcessGroup keystone-admin
     WSGIScriptAlias / %ADMINWSGI%
     WSGIApplicationGroup %{GLOBAL}
diff --git a/files/apts/keystone b/files/apts/keystone
index b7218b7..d316a42 100644
--- a/files/apts/keystone
+++ b/files/apts/keystone
@@ -6,6 +6,7 @@
 python-pysqlite2
 python-sqlalchemy
 python-mysqldb
+python-mysql.connector
 python-webob
 python-greenlet
 python-routes
diff --git a/files/apts/neutron b/files/apts/neutron
index 92e0a06..d3a08c7 100644
--- a/files/apts/neutron
+++ b/files/apts/neutron
@@ -15,6 +15,7 @@
 python-eventlet
 python-sqlalchemy
 python-mysqldb
+python-mysql.connector
 python-pyudev
 python-qpid # dist:precise
 dnsmasq-base
diff --git a/files/apts/nova b/files/apts/nova
index e779849..090ca4d 100644
--- a/files/apts/nova
+++ b/files/apts/nova
@@ -6,6 +6,7 @@
 iputils-arping
 mysql-server # NOPRIME
 python-mysqldb
+python-mysql.connector
 python-xattr # needed for glance which is needed for nova --- this shouldn't be here
 python-lxml # needed for glance which is needed for nova --- this shouldn't be here
 gawk
diff --git a/files/rpms-suse/keystone b/files/rpms-suse/keystone
index 403d82f..a734cb9 100644
--- a/files/rpms-suse/keystone
+++ b/files/rpms-suse/keystone
@@ -10,5 +10,6 @@
 python-greenlet
 python-lxml
 python-mysql
+python-mysql.connector
 python-pysqlite
 sqlite3
diff --git a/files/rpms-suse/neutron b/files/rpms-suse/neutron
index f3bafc7..79f5bff 100644
--- a/files/rpms-suse/neutron
+++ b/files/rpms-suse/neutron
@@ -10,6 +10,7 @@
 python-iso8601
 python-kombu
 python-mysql
+python-mysql.connector
 python-Paste
 python-PasteDeploy
 python-pyudev
diff --git a/files/rpms-suse/nova b/files/rpms-suse/nova
index 7a1160e..2a210e5 100644
--- a/files/rpms-suse/nova
+++ b/files/rpms-suse/nova
@@ -35,6 +35,7 @@
 python-lxml # needed for glance which is needed for nova --- this shouldn't be here
 python-mox
 python-mysql
+python-mysql.connector
 python-numpy # needed by websockify for spice console
 python-paramiko
 python-sqlalchemy-migrate
diff --git a/files/rpms/neutron b/files/rpms/neutron
index f02c02b..aaff48a 100644
--- a/files/rpms/neutron
+++ b/files/rpms/neutron
@@ -4,6 +4,7 @@
 ebtables
 iptables
 iputils
+mysql-connector-python
 mysql-server # NOPRIME
 openvswitch # NOPRIME
 python-boto
diff --git a/files/rpms/nova b/files/rpms/nova
index 6097991..ccee8a7 100644
--- a/files/rpms/nova
+++ b/files/rpms/nova
@@ -15,6 +15,7 @@
 libxml2-python
 numpy # needed by websockify for spice console
 m2crypto
+mysql-connector-python
 mysql-server # NOPRIME
 parted
 polkit
diff --git a/lib/cinder b/lib/cinder
index 38ce4d6..c78715e 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -470,11 +470,9 @@
         for be in ${CINDER_ENABLED_BACKENDS//,/ }; do
             BE_TYPE=${be%%:*}
             BE_NAME=${be##*:}
-            if type configure_cinder_backend_${BE_TYPE} >/dev/null 2>&1; then
-                # openstack volume type create --property volume_backend_name="${BE_TYPE}" ${BE_NAME}
-                cinder type-create ${BE_NAME} && \
-                    cinder type-key ${BE_NAME} set volume_backend_name="${BE_NAME}"
-            fi
+            # openstack volume type create --property volume_backend_name="${BE_TYPE}" ${BE_NAME}
+            cinder type-create ${BE_NAME} && \
+                cinder type-key ${BE_NAME} set volume_backend_name="${BE_NAME}"
         done
     fi
 }
diff --git a/lib/database b/lib/database
index 0661049..e226515 100644
--- a/lib/database
+++ b/lib/database
@@ -89,7 +89,7 @@
     # a multi-node DevStack installation.
 
     # NOTE: Don't specify ``/db`` in this string so we can use it for multiple services
-    BASE_SQL_CONN=${BASE_SQL_CONN:-${DATABASE_TYPE}://$DATABASE_USER:$DATABASE_PASSWORD@$DATABASE_HOST}
+    BASE_SQL_CONN=${BASE_SQL_CONN:-$(get_database_type)://$DATABASE_USER:$DATABASE_PASSWORD@$DATABASE_HOST}
 
     return 0
 }
@@ -120,6 +120,14 @@
     database_connection_url_$DATABASE_TYPE $db
 }
 
+function get_database_type {
+    if [[ -n "${SQLALCHEMY_DATABASE_DRIVER}" ]]; then
+        echo "${DATABASE_TYPE}+${SQLALCHEMY_DATABASE_DRIVER}"
+    else
+        echo "${DATABASE_TYPE}"
+    fi
+}
+
 
 # Restore xtrace
 $XTRACE
diff --git a/lib/ironic b/lib/ironic
index b05edcf..f5a7531 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -76,6 +76,12 @@
 IRONIC_DEPLOY_KERNEL=${IRONIC_DEPLOY_KERNEL:-}
 IRONIC_DEPLOY_ELEMENT=${IRONIC_DEPLOY_ELEMENT:-deploy-ironic}
 
+IRONIC_AGENT_TARBALL=${IRONIC_AGENT_TARBALL:-http://tarballs.openstack.org/ironic-python-agent/coreos/ipa-coreos.tar.gz}
+
+# Which deploy driver to use - valid choices right now
+# are 'pxe_ssh' and 'agent_ssh'.
+IRONIC_DEPLOY_DRIVER=${IRONIC_DEPLOY_DRIVER:-pxe_ssh}
+
 #TODO(agordeev): replace 'ubuntu' with host distro name getting
 IRONIC_DEPLOY_FLAVOR=${IRONIC_DEPLOY_FLAVOR:-ubuntu $IRONIC_DEPLOY_ELEMENT}
 
@@ -218,6 +224,22 @@
     if [[ "$IRONIC_VM_LOG_CONSOLE" == "True" ]] ; then
         iniset $IRONIC_CONF_FILE pxe pxe_append_params "nofb nomodeset vga=normal console=ttyS0"
     fi
+    if [[ "$IRONIC_DEPLOY_DRIVER" == "agent_ssh" ]] ; then
+        if [[ "$SWIFT_ENABLE_TEMPURLS" == "True" ]] ; then
+            iniset $IRONIC_CONF_FILE glance swift_temp_url_key $SWIFT_TEMPURL_KEY
+        else
+            die $LINENO "SWIFT_ENABLE_TEMPURLS must be True to use agent_ssh driver in Ironic."
+        fi
+        iniset $IRONIC_CONF_FILE glance swift_endpoint_url http://${HOST_IP}:8080
+        iniset $IRONIC_CONF_FILE glance swift_api_version v1
+        iniset $IRONIC_CONF_FILE glance swift_account AUTH_${SERVICE_TENANT}
+        iniset $IRONIC_CONF_FILE glance swift_container glance
+        iniset $IRONIC_CONF_FILE glance swift_temp_url_duration 3600
+        iniset $IRONIC_CONF_FILE agent heartbeat_timeout 30
+        if [[ "$IRONIC_VM_LOG_CONSOLE" == "True" ]] ; then
+            iniset $IRONIC_CONF_FILE agent agent_pxe_append_params "nofb nomodeset vga=normal console=ttyS0"
+        fi
+    fi
 }
 
 # create_ironic_cache_dir() - Part of the init_ironic() process
@@ -365,10 +387,21 @@
 function enroll_vms {
     local chassis_id=$(ironic chassis-create -d "ironic test chassis" | grep " uuid " | get_field 2)
     local idx=0
+
+    if [[ "$IRONIC_DEPLOY_DRIVER" == "pxe_ssh" ]] ; then
+        local _IRONIC_DEPLOY_KERNEL_KEY=pxe_deploy_kernel
+        local _IRONIC_DEPLOY_RAMDISK_KEY=pxe_deploy_ramdisk
+    elif [[ "$IRONIC_DEPLOY_DRIVER" == "agent_ssh" ]] ; then
+        local _IRONIC_DEPLOY_KERNEL_KEY=deploy_kernel
+        local _IRONIC_DEPLOY_RAMDISK_KEY=deploy_ramdisk
+    fi
+
     while read MAC; do
-        local node_id=$(ironic node-create --chassis_uuid $chassis_id --driver pxe_ssh \
-            -i pxe_deploy_kernel=$IRONIC_DEPLOY_KERNEL_ID \
-            -i pxe_deploy_ramdisk=$IRONIC_DEPLOY_RAMDISK_ID \
+
+        local node_id=$(ironic node-create --chassis_uuid $chassis_id \
+            --driver $IRONIC_DEPLOY_DRIVER \
+            -i $_IRONIC_DEPLOY_KERNEL_KEY=$IRONIC_DEPLOY_KERNEL_ID \
+            -i $_IRONIC_DEPLOY_RAMDISK_KEY=$IRONIC_DEPLOY_RAMDISK_ID \
             -i ssh_virt_type=$IRONIC_SSH_VIRT_TYPE \
             -i ssh_address=$IRONIC_VM_SSH_ADDRESS \
             -i ssh_port=$IRONIC_VM_SSH_PORT \
@@ -480,13 +513,27 @@
         if [ "$IRONIC_BUILD_DEPLOY_RAMDISK" = "True" ]; then
             # we can build them only if we're not offline
             if [ "$OFFLINE" != "True" ]; then
-                $DIB_DIR/bin/ramdisk-image-create $IRONIC_DEPLOY_FLAVOR \
-                    -o $TOP_DIR/files/ir-deploy
+                if [ "$IRONIC_DEPLOY_RAMDISK" == "agent_ssh" ]; then
+                    die $LINENO "Ironic-python-agent build is not yet supported"
+                else
+                    $DIB_DIR/bin/ramdisk-image-create $IRONIC_DEPLOY_FLAVOR \
+                        -o $TOP_DIR/files/ir-deploy
+                fi
             else
                 die $LINENO "Deploy kernel+ramdisk files don't exist and cannot be build in OFFLINE mode"
             fi
         else
-            die $LINENO "Deploy kernel+ramdisk files don't exist and their building was disabled explicitly by IRONIC_BUILD_DEPLOY_RAMDISK"
+            if [ "$IRONIC_DEPLOY_DRIVER" == "agent_ssh" ]; then
+                # download the agent image tarball
+                wget "$IRONIC_AGENT_TARBALL" -O ironic_agent_tarball.tar.gz
+                tar zxfv ironic_agent_tarball.tar.gz
+                mv UPLOAD/coreos_production_pxe.vmlinuz $IRONIC_DEPLOY_KERNEL_PATH
+                mv UPLOAD/coreos_production_pxe_image-oem.cpio.gz $IRONIC_DEPLOY_RAMDISK_PATH
+                rm -rf UPLOAD
+                rm ironic_agent_tarball.tar.gz
+            else
+                die $LINENO "Deploy kernel+ramdisk files don't exist and their building was disabled explicitly by IRONIC_BUILD_DEPLOY_RAMDISK"
+            fi
         fi
     fi
 
@@ -500,6 +547,7 @@
         image create \
         $(basename $IRONIC_DEPLOY_KERNEL_PATH) \
         --public --disk-format=aki \
+        --container-format=aki \
         < $IRONIC_DEPLOY_KERNEL_PATH  | grep ' id ' | get_field 2)
     IRONIC_DEPLOY_RAMDISK_ID=$(openstack \
         --os-token $token \
@@ -507,6 +555,7 @@
         image create \
         $(basename $IRONIC_DEPLOY_RAMDISK_PATH) \
         --public --disk-format=ari \
+        --container-format=ari \
         < $IRONIC_DEPLOY_RAMDISK_PATH  | grep ' id ' | get_field 2)
 }
 
diff --git a/lib/marconi b/lib/marconi
deleted file mode 100644
index e05518c..0000000
--- a/lib/marconi
+++ /dev/null
@@ -1,211 +0,0 @@
-# lib/marconi
-# Install and start **Marconi** service
-
-# To enable a minimal set of Marconi services, add the following to localrc:
-#
-#     enable_service marconi-server
-#
-# Dependencies:
-# - functions
-# - OS_AUTH_URL for auth in api
-# - DEST set to the destination directory
-# - SERVICE_PASSWORD, SERVICE_TENANT_NAME for auth in api
-# - STACK_USER service user
-
-# stack.sh
-# ---------
-# install_marconi
-# configure_marconi
-# init_marconi
-# start_marconi
-# stop_marconi
-# cleanup_marconi
-
-# Save trace setting
-XTRACE=$(set +o | grep xtrace)
-set +o xtrace
-
-
-# Defaults
-# --------
-
-# Set up default directories
-MARCONI_DIR=$DEST/marconi
-MARCONICLIENT_DIR=$DEST/python-marconiclient
-MARCONI_CONF_DIR=/etc/marconi
-MARCONI_CONF=$MARCONI_CONF_DIR/marconi.conf
-MARCONI_API_LOG_DIR=/var/log/marconi
-MARCONI_API_LOG_FILE=$MARCONI_API_LOG_DIR/queues.log
-MARCONI_AUTH_CACHE_DIR=${MARCONI_AUTH_CACHE_DIR:-/var/cache/marconi}
-
-# Support potential entry-points console scripts
-MARCONI_BIN_DIR=$(get_python_exec_prefix)
-
-# Set up database backend
-MARCONI_BACKEND=${MARCONI_BACKEND:-mongodb}
-
-
-# Set Marconi repository
-MARCONI_REPO=${MARCONI_REPO:-${GIT_BASE}/openstack/marconi.git}
-MARCONI_BRANCH=${MARCONI_BRANCH:-master}
-
-# Set client library repository
-MARCONICLIENT_REPO=${MARCONICLIENT_REPO:-${GIT_BASE}/openstack/python-marconiclient.git}
-MARCONICLIENT_BRANCH=${MARCONICLIENT_BRANCH:-master}
-
-# Set Marconi Connection Info
-MARCONI_SERVICE_HOST=${MARCONI_SERVICE_HOST:-$SERVICE_HOST}
-MARCONI_SERVICE_PORT=${MARCONI_SERVICE_PORT:-8888}
-MARCONI_SERVICE_PROTOCOL=${MARCONI_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
-
-# Tell Tempest this project is present
-TEMPEST_SERVICES+=,marconi
-
-
-# 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 {
-    if ! timeout $SERVICE_TIMEOUT sh -c "while ! mongo marconi --eval 'db.dropDatabase();'; do sleep 1; done"; then
-        die $LINENO "Mongo DB did not start"
-    else
-        full_version=$(mongo marconi --eval 'db.dropDatabase();')
-        mongo_version=`echo $full_version | cut -d' ' -f4`
-        required_mongo_version='2.2'
-        if [[ $mongo_version < $required_mongo_version ]]; then
-            die $LINENO "Marconi needs Mongo DB version >= 2.2 to run."
-        fi
-    fi
-}
-
-# configure_marconiclient() - Set config files, create data dirs, etc
-function configure_marconiclient {
-    setup_develop $MARCONICLIENT_DIR
-}
-
-# configure_marconi() - Set config files, create data dirs, etc
-function configure_marconi {
-    setup_develop $MARCONI_DIR
-
-    [ ! -d $MARCONI_CONF_DIR ] && sudo mkdir -m 755 -p $MARCONI_CONF_DIR
-    sudo chown $USER $MARCONI_CONF_DIR
-
-    [ ! -d $MARCONI_API_LOG_DIR ] &&  sudo mkdir -m 755 -p $MARCONI_API_LOG_DIR
-    sudo chown $USER $MARCONI_API_LOG_DIR
-
-    iniset $MARCONI_CONF DEFAULT verbose True
-    iniset $MARCONI_CONF DEFAULT use_syslog $SYSLOG
-    iniset $MARCONI_CONF DEFAULT log_file $MARCONI_API_LOG_FILE
-    iniset $MARCONI_CONF 'drivers:transport:wsgi' bind $MARCONI_SERVICE_HOST
-
-    iniset $MARCONI_CONF keystone_authtoken auth_protocol http
-    iniset $MARCONI_CONF keystone_authtoken admin_user marconi
-    iniset $MARCONI_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
-    iniset $MARCONI_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $MARCONI_CONF keystone_authtoken signing_dir $MARCONI_AUTH_CACHE_DIR
-
-    if [ "$MARCONI_BACKEND" = 'mysql' ] || [ "$MARCONI_BACKEND" = 'postgresql' ] ; then
-        iniset $MARCONI_CONF drivers storage sqlalchemy
-        iniset $MARCONI_CONF 'drivers:storage:sqlalchemy' uri `database_connection_url marconi`
-    elif [ "$MARCONI_BACKEND" = 'mongodb' ] ; then
-        iniset $MARCONI_CONF  drivers storage mongodb
-        iniset $MARCONI_CONF 'drivers:storage:mongodb' uri mongodb://localhost:27017/marconi
-        configure_mongodb
-        cleanup_marconi
-    fi
-}
-
-function configure_mongodb {
-    # Set nssize to 2GB. This increases the number of namespaces supported
-    # # per database.
-    if is_ubuntu; then
-        sudo sed -i -e "
-            s|[^ \t]*#[ \t]*\(nssize[ \t]*=.*\$\)|\1|
-            s|^\(nssize[ \t]*=[ \t]*\).*\$|\1 2047|
-        " /etc/mongodb.conf
-        restart_service mongodb
-    elif is_fedora; then
-        sudo sed -i '/--nssize/!s/OPTIONS=\"/OPTIONS=\"--nssize 2047 /' /etc/sysconfig/mongod
-        restart_service mongod
-    fi
-}
-
-# init_marconi() - Initialize etc.
-function init_marconi {
-    # Create cache dir
-    sudo mkdir -p $MARCONI_AUTH_CACHE_DIR
-    sudo chown $STACK_USER $MARCONI_AUTH_CACHE_DIR
-    rm -f $MARCONI_AUTH_CACHE_DIR/*
-}
-
-# install_marconi() - Collect source and prepare
-function install_marconi {
-    git_clone $MARCONI_REPO $MARCONI_DIR $MARCONI_BRANCH
-    setup_develop $MARCONI_DIR
-}
-
-# install_marconiclient() - Collect source and prepare
-function install_marconiclient {
-    git_clone $MARCONICLIENT_REPO $MARCONICLIENT_DIR $MARCONICLIENT_BRANCH
-    setup_develop $MARCONICLIENT_DIR
-}
-
-# start_marconi() - Start running processes, including screen
-function start_marconi {
-    if [[ "$USE_SCREEN" = "False" ]]; then
-        screen_it marconi-server "marconi-server --config-file $MARCONI_CONF --daemon"
-    else
-        screen_it marconi-server "marconi-server --config-file $MARCONI_CONF"
-    fi
-
-    echo "Waiting for Marconi to start..."
-    if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- $MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT/v1/health; do sleep 1; done"; then
-        die $LINENO "Marconi did not start"
-    fi
-}
-
-# stop_marconi() - Stop running processes
-function stop_marconi {
-    # Kill the marconi screen windows
-    for serv in marconi-server; do
-        screen -S $SCREEN_NAME -p $serv -X kill
-    done
-}
-
-function create_marconi_accounts {
-    SERVICE_TENANT=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
-    ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
-
-    MARCONI_USER=$(get_or_create_user "marconi" \
-        "$SERVICE_PASSWORD" $SERVICE_TENANT)
-    get_or_add_user_role $ADMIN_ROLE $MARCONI_USER $SERVICE_TENANT
-
-    if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
-
-        MARCONI_SERVICE=$(get_or_create_service "marconi" \
-            "queuing" "Marconi Service")
-        get_or_create_endpoint $MARCONI_SERVICE \
-            "$REGION_NAME" \
-            "$MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT" \
-            "$MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT" \
-            "$MARCONI_SERVICE_PROTOCOL://$MARCONI_SERVICE_HOST:$MARCONI_SERVICE_PORT"
-    fi
-
-}
-
-
-# Restore xtrace
-$XTRACE
-
-# Local variables:
-# mode: shell-script
-# End:
diff --git a/lib/neutron_plugins/linuxbridge_agent b/lib/neutron_plugins/linuxbridge_agent
index 82b5fc9..2638dd3 100644
--- a/lib/neutron_plugins/linuxbridge_agent
+++ b/lib/neutron_plugins/linuxbridge_agent
@@ -47,6 +47,7 @@
         iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.firewall.NoopFirewallDriver
     fi
     AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-linuxbridge-agent"
+    iniset /$Q_PLUGIN_CONF_FILE agent tunnel_types $Q_TUNNEL_TYPES
     # Define extra "AGENT" configuration options when q-agt is configured by defining
     # the array ``Q_AGENT_EXTRA_AGENT_OPTS``.
     # For Example: ``Q_AGENT_EXTRA_AGENT_OPTS=(foo=true bar=2)``
diff --git a/lib/neutron_plugins/ml2 b/lib/neutron_plugins/ml2
index 42dd57f..44b947f 100644
--- a/lib/neutron_plugins/ml2
+++ b/lib/neutron_plugins/ml2
@@ -6,13 +6,13 @@
 set +o xtrace
 
 # Enable this to simply and quickly enable tunneling with ML2.
-# Select either 'gre', 'vxlan', or '(gre vxlan)'
+# Select either 'gre', 'vxlan', or 'gre,vxlan'
 Q_ML2_TENANT_NETWORK_TYPE=${Q_ML2_TENANT_NETWORK_TYPE:-"vxlan"}
 # This has to be set here since the agent will set this in the config file
 if [[ "$Q_ML2_TENANT_NETWORK_TYPE" == "gre" || "$Q_ML2_TENANT_NETWORK_TYPE" == "vxlan" ]]; then
-    Q_AGENT_EXTRA_AGENT_OPTS+=(tunnel_types=$Q_ML2_TENANT_NETWORK_TYPE)
+    Q_TUNNEL_TYPES=$Q_ML2_TENANT_NETWORK_TYPE
 elif [[ "$ENABLE_TENANT_TUNNELS" == "True" ]]; then
-    Q_AGENT_EXTRA_AGENT_OPTS+=(tunnel_types=gre)
+    Q_TUNNEL_TYPES=gre
 fi
 
 # Default openvswitch L2 agent
diff --git a/lib/neutron_plugins/ofagent_agent b/lib/neutron_plugins/ofagent_agent
index 66283ad..b4c2ada 100644
--- a/lib/neutron_plugins/ofagent_agent
+++ b/lib/neutron_plugins/ofagent_agent
@@ -71,6 +71,7 @@
     fi
     AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-ofagent-agent"
 
+    iniset /$Q_PLUGIN_CONF_FILE agent tunnel_types $Q_TUNNEL_TYPES
     # Define extra "AGENT" configuration options when q-agt is configured by defining
     # defining the array ``Q_AGENT_EXTRA_AGENT_OPTS``.
     # For Example: ``Q_AGENT_EXTRA_AGENT_OPTS=(foo=true bar=2)``
diff --git a/lib/neutron_plugins/openvswitch_agent b/lib/neutron_plugins/openvswitch_agent
index 5adb0c5..3fc37de 100644
--- a/lib/neutron_plugins/openvswitch_agent
+++ b/lib/neutron_plugins/openvswitch_agent
@@ -102,6 +102,7 @@
         # Set root wrap
         iniset "/$Q_PLUGIN_CONF_FILE.domU" agent root_helper "$Q_RR_COMMAND"
     fi
+    iniset /$Q_PLUGIN_CONF_FILE agent tunnel_types $Q_TUNNEL_TYPES
     # Define extra "AGENT" configuration options when q-agt is configured by defining
     # defining the array ``Q_AGENT_EXTRA_AGENT_OPTS``.
     # For Example: ``Q_AGENT_EXTRA_AGENT_OPTS=(foo=true bar=2)``
diff --git a/lib/stackforge b/lib/stackforge
index e6528af..b744318 100644
--- a/lib/stackforge
+++ b/lib/stackforge
@@ -35,10 +35,6 @@
 
 # install_stackforge() - Collect source and prepare
 function install_stackforge {
-    # TODO(sdague): remove this once we get to Icehouse, this just makes
-    # for a smoother transition of existing users.
-    cleanup_stackforge
-
     git_clone $WSME_REPO $WSME_DIR $WSME_BRANCH
     setup_package $WSME_DIR
 
@@ -46,20 +42,6 @@
     setup_package $PECAN_DIR
 }
 
-# cleanup_stackforge() - purge possibly old versions of stackforge libraries
-function cleanup_stackforge {
-    # this means we've got an old version installed, lets get rid of it
-    # otherwise python hates itself
-    for lib in wsme pecan; do
-        if ! python -c "import $lib" 2>/dev/null; then
-            echo "Found old $lib... removing to ensure consistency"
-            local PIP_CMD=$(get_pip_command)
-            pip_install $lib
-            sudo $PIP_CMD uninstall -y $lib
-        fi
-    done
-}
-
 # Restore xtrace
 $XTRACE
 
diff --git a/lib/zaqar b/lib/zaqar
new file mode 100644
index 0000000..0d33df2
--- /dev/null
+++ b/lib/zaqar
@@ -0,0 +1,211 @@
+# lib/zaqar
+# Install and start **Zaqar** service
+
+# To enable a minimal set of Zaqar services, add the following to localrc:
+#
+#     enable_service zaqar-server
+#
+# Dependencies:
+# - functions
+# - OS_AUTH_URL for auth in api
+# - DEST set to the destination directory
+# - SERVICE_PASSWORD, SERVICE_TENANT_NAME for auth in api
+# - STACK_USER service user
+
+# stack.sh
+# ---------
+# install_zaqar
+# configure_zaqar
+# init_zaqar
+# start_zaqar
+# stop_zaqar
+# cleanup_zaqar
+
+# Save trace setting
+XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# Set up default directories
+ZAQAR_DIR=$DEST/zaqar
+ZAQARCLIENT_DIR=$DEST/python-zaqarclient
+ZAQAR_CONF_DIR=/etc/zaqar
+ZAQAR_CONF=$ZAQAR_CONF_DIR/zaqar.conf
+ZAQAR_API_LOG_DIR=/var/log/zaqar
+ZAQAR_API_LOG_FILE=$ZAQAR_API_LOG_DIR/queues.log
+ZAQAR_AUTH_CACHE_DIR=${ZAQAR_AUTH_CACHE_DIR:-/var/cache/zaqar}
+
+# Support potential entry-points console scripts
+ZAQAR_BIN_DIR=$(get_python_exec_prefix)
+
+# Set up database backend
+ZAQAR_BACKEND=${ZAQAR_BACKEND:-mongodb}
+
+
+# Set Zaqar repository
+ZAQAR_REPO=${ZAQAR_REPO:-${GIT_BASE}/openstack/zaqar.git}
+ZAQAR_BRANCH=${ZAQAR_BRANCH:-master}
+
+# Set client library repository
+ZAQARCLIENT_REPO=${ZAQARCLIENT_REPO:-${GIT_BASE}/openstack/python-zaqarclient.git}
+ZAQARCLIENT_BRANCH=${ZAQARCLIENT_BRANCH:-master}
+
+# Set Zaqar Connection Info
+ZAQAR_SERVICE_HOST=${ZAQAR_SERVICE_HOST:-$SERVICE_HOST}
+ZAQAR_SERVICE_PORT=${ZAQAR_SERVICE_PORT:-8888}
+ZAQAR_SERVICE_PROTOCOL=${ZAQAR_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
+
+# Tell Tempest this project is present
+TEMPEST_SERVICES+=,zaqar
+
+
+# Functions
+# ---------
+
+# Test if any Zaqar services are enabled
+# is_zaqar_enabled
+function is_zaqar_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"zaqar-" ]] && return 0
+    return 1
+}
+
+# cleanup_zaqar() - Remove residual data files, anything left over from previous
+# runs that a clean run would need to clean up
+function cleanup_zaqar {
+    if ! timeout $SERVICE_TIMEOUT sh -c "while ! mongo zaqar --eval 'db.dropDatabase();'; do sleep 1; done"; then
+        die $LINENO "Mongo DB did not start"
+    else
+        full_version=$(mongo zaqar --eval 'db.dropDatabase();')
+        mongo_version=`echo $full_version | cut -d' ' -f4`
+        required_mongo_version='2.2'
+        if [[ $mongo_version < $required_mongo_version ]]; then
+            die $LINENO "Zaqar needs Mongo DB version >= 2.2 to run."
+        fi
+    fi
+}
+
+# configure_zaqarclient() - Set config files, create data dirs, etc
+function configure_zaqarclient {
+    setup_develop $ZAQARCLIENT_DIR
+}
+
+# configure_zaqar() - Set config files, create data dirs, etc
+function configure_zaqar {
+    setup_develop $ZAQAR_DIR
+
+    [ ! -d $ZAQAR_CONF_DIR ] && sudo mkdir -m 755 -p $ZAQAR_CONF_DIR
+    sudo chown $USER $ZAQAR_CONF_DIR
+
+    [ ! -d $ZAQAR_API_LOG_DIR ] &&  sudo mkdir -m 755 -p $ZAQAR_API_LOG_DIR
+    sudo chown $USER $ZAQAR_API_LOG_DIR
+
+    iniset $ZAQAR_CONF DEFAULT verbose True
+    iniset $ZAQAR_CONF DEFAULT use_syslog $SYSLOG
+    iniset $ZAQAR_CONF DEFAULT log_file $ZAQAR_API_LOG_FILE
+    iniset $ZAQAR_CONF 'drivers:transport:wsgi' bind $ZAQAR_SERVICE_HOST
+
+    iniset $ZAQAR_CONF keystone_authtoken auth_protocol http
+    iniset $ZAQAR_CONF keystone_authtoken admin_user zaqar
+    iniset $ZAQAR_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
+    iniset $ZAQAR_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
+    iniset $ZAQAR_CONF keystone_authtoken signing_dir $ZAQAR_AUTH_CACHE_DIR
+
+    if [ "$ZAQAR_BACKEND" = 'mysql' ] || [ "$ZAQAR_BACKEND" = 'postgresql' ] ; then
+        iniset $ZAQAR_CONF drivers storage sqlalchemy
+        iniset $ZAQAR_CONF 'drivers:storage:sqlalchemy' uri `database_connection_url zaqar`
+    elif [ "$ZAQAR_BACKEND" = 'mongodb' ] ; then
+        iniset $ZAQAR_CONF  drivers storage mongodb
+        iniset $ZAQAR_CONF 'drivers:storage:mongodb' uri mongodb://localhost:27017/zaqar
+        configure_mongodb
+        cleanup_zaqar
+    fi
+}
+
+function configure_mongodb {
+    # Set nssize to 2GB. This increases the number of namespaces supported
+    # # per database.
+    if is_ubuntu; then
+        sudo sed -i -e "
+            s|[^ \t]*#[ \t]*\(nssize[ \t]*=.*\$\)|\1|
+            s|^\(nssize[ \t]*=[ \t]*\).*\$|\1 2047|
+        " /etc/mongodb.conf
+        restart_service mongodb
+    elif is_fedora; then
+        sudo sed -i '/--nssize/!s/OPTIONS=\"/OPTIONS=\"--nssize 2047 /' /etc/sysconfig/mongod
+        restart_service mongod
+    fi
+}
+
+# init_zaqar() - Initialize etc.
+function init_zaqar {
+    # Create cache dir
+    sudo mkdir -p $ZAQAR_AUTH_CACHE_DIR
+    sudo chown $STACK_USER $ZAQAR_AUTH_CACHE_DIR
+    rm -f $ZAQAR_AUTH_CACHE_DIR/*
+}
+
+# install_zaqar() - Collect source and prepare
+function install_zaqar {
+    git_clone $ZAQAR_REPO $ZAQAR_DIR $ZAQAR_BRANCH
+    setup_develop $ZAQAR_DIR
+}
+
+# install_zaqarclient() - Collect source and prepare
+function install_zaqarclient {
+    git_clone $ZAQARCLIENT_REPO $ZAQARCLIENT_DIR $ZAQARCLIENT_BRANCH
+    setup_develop $ZAQARCLIENT_DIR
+}
+
+# start_zaqar() - Start running processes, including screen
+function start_zaqar {
+    if [[ "$USE_SCREEN" = "False" ]]; then
+        screen_it zaqar-server "zaqar-server --config-file $ZAQAR_CONF --daemon"
+    else
+        screen_it zaqar-server "zaqar-server --config-file $ZAQAR_CONF"
+    fi
+
+    echo "Waiting for Zaqar to start..."
+    if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- $ZAQAR_SERVICE_PROTOCOL://$ZAQAR_SERVICE_HOST:$ZAQAR_SERVICE_PORT/v1/health; do sleep 1; done"; then
+        die $LINENO "Zaqar did not start"
+    fi
+}
+
+# stop_zaqar() - Stop running processes
+function stop_zaqar {
+    # Kill the zaqar screen windows
+    for serv in zaqar-server; do
+        screen -S $SCREEN_NAME -p $serv -X kill
+    done
+}
+
+function create_zaqar_accounts {
+    SERVICE_TENANT=$(openstack project list | awk "/ $SERVICE_TENANT_NAME / { print \$2 }")
+    ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
+
+    ZAQAR_USER=$(get_or_create_user "zaqar" \
+        "$SERVICE_PASSWORD" $SERVICE_TENANT)
+    get_or_add_user_role $ADMIN_ROLE $ZAQAR_USER $SERVICE_TENANT
+
+    if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
+
+        ZAQAR_SERVICE=$(get_or_create_service "zaqar" \
+            "queuing" "Zaqar Service")
+        get_or_create_endpoint $ZAQAR_SERVICE \
+            "$REGION_NAME" \
+            "$ZAQAR_SERVICE_PROTOCOL://$ZAQAR_SERVICE_HOST:$ZAQAR_SERVICE_PORT" \
+            "$ZAQAR_SERVICE_PROTOCOL://$ZAQAR_SERVICE_HOST:$ZAQAR_SERVICE_PORT" \
+            "$ZAQAR_SERVICE_PROTOCOL://$ZAQAR_SERVICE_HOST:$ZAQAR_SERVICE_PORT"
+    fi
+
+}
+
+
+# Restore xtrace
+$XTRACE
+
+# Local variables:
+# mode: shell-script
+# End:
diff --git a/stack.sh b/stack.sh
index 7a7655c..9b9c245 100755
--- a/stack.sh
+++ b/stack.sh
@@ -631,7 +631,11 @@
 
     if [[ $r -ne 0 ]]; then
         echo "Error on exit"
-        ./tools/worlddump.py -d $LOGDIR
+        if [[ -z $LOGDIR ]]; then
+            ./tools/worlddump.py
+        else
+            ./tools/worlddump.py -d $LOGDIR
+        fi
     fi
 
     exit $r
diff --git a/stackrc b/stackrc
index fb84366..5149b78 100644
--- a/stackrc
+++ b/stackrc
@@ -52,6 +52,18 @@
     ENABLED_SERVICES+=,rabbit,tempest,mysql
 fi
 
+# SQLAlchemy supports multiple database drivers for each database server
+# type. For example, deployer may use MySQLdb, MySQLConnector, or oursql
+# to access MySQL database.
+#
+# When defined, the variable controls which database driver is used to
+# connect to database server. Otherwise using default driver defined for
+# each database type.
+#
+# You can find the list of currently supported drivers for each database
+# type at: http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html
+# SQLALCHEMY_DATABASE_DRIVER="mysqldb"
+
 # Global toggle for enabling services under mod_wsgi. If this is set to
 # ``True`` all services that use HTTPD + mod_wsgi as the preferred method of
 # deployment, will be deployed under Apache. If this is set to ``False`` all
@@ -366,6 +378,15 @@
         DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-0.3.0-x86_64-disk}
         IMAGE_URLS=${IMAGE_URLS:-"https://github.com/downloads/citrix-openstack/warehouse/cirros-0.3.0-x86_64-disk.vhd.tgz"}
         IMAGE_URLS+=",http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-uec.tar.gz";;
+    ironic)
+        # Ironic can do both partition and full disk images, depending on the driver
+        if [[ "$IRONIC_DEPLOY_DRIVER" == "agent_ssh" ]]; then
+            DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-x86_64-disk}
+        else
+            DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-x86_64-uec}
+        fi
+        IMAGE_URLS=${IMAGE_URLS:-"http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-uec.tar.gz"}
+        IMAGE_URLS+=",http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-disk.img";;
     *) # Default to Cirros with kernel, ramdisk and disk image
         DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-uec}
         IMAGE_URLS=${IMAGE_URLS:-"http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-uec.tar.gz"};;