Merge "Upgrade to cirros 0.3.2"
diff --git a/HACKING.rst b/HACKING.rst
index 5c15537..83455e3 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -20,7 +20,7 @@
 contains the usual links for blueprints, bugs, tec.
 
 __ contribute_
-.. _contribute: http://wiki.openstack.org/HowToContribute.
+.. _contribute: http://wiki.openstack.org/HowToContribute
 
 __ lp_
 .. _lp: https://launchpad.net/~devstack
@@ -231,7 +231,7 @@
 
 Bash Style Guidelines
 ~~~~~~~~~~~~~~~~~~~~~
-Devstack defines a bash set of best practices for maintaining large
+DevStack defines a bash set of best practices for maintaining large
 collections of bash scripts. These should be considered as part of the
 review process.
 
diff --git a/README.md b/README.md
index 89e3855..37b960e 100644
--- a/README.md
+++ b/README.md
@@ -2,11 +2,16 @@
 
 # Goals
 
-* To quickly build dev OpenStack environments in a clean Ubuntu or Fedora environment
-* To describe working configurations of OpenStack (which code branches work together?  what do config files look like for those branches?)
-* To make it easier for developers to dive into OpenStack so that they can productively contribute without having to understand every part of the system at once
+* To quickly build dev OpenStack environments in a clean Ubuntu or Fedora
+  environment
+* To describe working configurations of OpenStack (which code branches
+  work together?  what do config files look like for those branches?)
+* To make it easier for developers to dive into OpenStack so that they can
+  productively contribute without having to understand every part of the
+  system at once
 * To make it easy to prototype cross-project features
-* To provide an environment for the OpenStack CI testing on every commit to the projects
+* To provide an environment for the OpenStack CI testing on every commit
+  to the projects
 
 Read more at http://devstack.org.
 
@@ -42,12 +47,14 @@
 
     ./stack.sh
 
-When the script finishes executing, you should be able to access OpenStack endpoints, like so:
+When the script finishes executing, you should be able to access OpenStack
+endpoints, like so:
 
 * Horizon: http://myhost/
 * Keystone: http://myhost:5000/v2.0/
 
-We also provide an environment file that you can use to interact with your cloud via CLI:
+We also provide an environment file that you can use to interact with your
+cloud via CLI:
 
     # source openrc file to load your environment with OpenStack CLI creds
     . openrc
@@ -63,7 +70,12 @@
 
 # DevStack Execution Environment
 
-DevStack runs rampant over the system it runs on, installing things and uninstalling other things.  Running this on a system you care about is a recipe for disappointment, or worse.  Alas, we're all in the virtualization business here, so run it in a VM.  And take advantage of the snapshot capabilities of your hypervisor of choice to reduce testing cycle times.  You might even save enough time to write one more feature before the next feature freeze...
+DevStack runs rampant over the system it runs on, installing things and
+uninstalling other things.  Running this on a system you care about is a recipe
+for disappointment, or worse.  Alas, we're all in the virtualization business
+here, so run it in a VM.  And take advantage of the snapshot capabilities
+of your hypervisor of choice to reduce testing cycle times.  You might even save
+enough time to write one more feature before the next feature freeze...
 
 ``stack.sh`` needs to have root access for a lot of tasks, but uses ``sudo``
 for all of those tasks.  However, it needs to be not-root for most of its
@@ -93,7 +105,8 @@
 
 # Database Backend
 
-Multiple database backends are available. The available databases are defined in the lib/databases directory.
+Multiple database backends are available. The available databases are defined
+in the lib/databases directory.
 `mysql` is the default database, choose a different one by putting the
 following in the `localrc` section:
 
@@ -124,7 +137,7 @@
 `APACHE_ENABLED_SERVICES` in your ``localrc`` section.  Remember to
 enable these services at first as above.
 
-    APACHE_ENABLED_SERVICES+=keystone,swift
+    APACHE_ENABLED_SERVICES+=key,swift
 
 # Swift
 
@@ -235,10 +248,14 @@
 (e.g. linuxbridge).
 
     Variable Name                    Notes
-    -------------------------------------------------------------------------------------
-    Q_AGENT                          This specifies which agent to run with the ML2 Plugin (either `openvswitch` or `linuxbridge`).
-    Q_ML2_PLUGIN_MECHANISM_DRIVERS   The ML2 MechanismDrivers to load. The default is none. Note, ML2 will work with the OVS and LinuxBridge agents by default.
-    Q_ML2_PLUGIN_TYPE_DRIVERS        The ML2 TypeDrivers to load. Defaults to all available TypeDrivers.
+    ----------------------------------------------------------------------------
+    Q_AGENT                          This specifies which agent to run with the
+                                     ML2 Plugin (either `openvswitch` or `linuxbridge`).
+    Q_ML2_PLUGIN_MECHANISM_DRIVERS   The ML2 MechanismDrivers to load. The default
+                                     is none. Note, ML2 will work with the OVS
+                                     and LinuxBridge agents by default.
+    Q_ML2_PLUGIN_TYPE_DRIVERS        The ML2 TypeDrivers to load. Defaults to
+                                     all available TypeDrivers.
     Q_ML2_PLUGIN_GRE_TYPE_OPTIONS    GRE TypeDriver options. Defaults to none.
     Q_ML2_PLUGIN_VXLAN_TYPE_OPTIONS  VXLAN TypeDriver options. Defaults to none.
     Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS   VLAN TypeDriver options. Defaults to none.
@@ -262,14 +279,16 @@
 
 # Tempest
 
-If tempest has been successfully configured, a basic set of smoke tests can be run as follows:
+If tempest has been successfully configured, a basic set of smoke
+tests can be run as follows:
 
     $ cd /opt/stack/tempest
     $ nosetests tempest/scenario/test_network_basic_ops.py
 
 # DevStack on Xenserver
 
-If you would like to use Xenserver as the hypervisor, please refer to the instructions in `./tools/xen/README.md`.
+If you would like to use Xenserver as the hypervisor, please refer
+to the instructions in `./tools/xen/README.md`.
 
 # Additional Projects
 
@@ -283,8 +302,10 @@
 
 # Multi-Node Setup
 
-A more interesting setup involves running multiple compute nodes, with Neutron networks connecting VMs on different compute nodes.
-You should run at least one "controller node", which should have a `stackrc` that includes at least:
+A more interesting setup involves running multiple compute nodes, with Neutron
+networks connecting VMs on different compute nodes.
+You should run at least one "controller node", which should have a `stackrc`
+that includes at least:
 
     disable_service n-net
     enable_service q-svc
@@ -299,7 +320,8 @@
 
     SCHEDULER=nova.scheduler.simple.SimpleScheduler
 
-You can then run many compute nodes, each of which should have a `stackrc` which includes the following, with the IP address of the above controller node:
+You can then run many compute nodes, each of which should have a `stackrc`
+which includes the following, with the IP address of the above controller node:
 
     ENABLED_SERVICES=n-cpu,rabbit,g-api,neutron,q-agt
     SERVICE_HOST=[IP of controller node]
@@ -310,22 +332,31 @@
 
 # Cells
 
-Cells is a new scaling option with a full spec at http://wiki.openstack.org/blueprint-nova-compute-cells.
+Cells is a new scaling option with a full spec at:
+http://wiki.openstack.org/blueprint-nova-compute-cells.
 
 To setup a cells environment add the following to your `localrc` section:
 
     enable_service n-cell
 
-Be aware that there are some features currently missing in cells, one notable one being security groups.  The exercises have been patched to disable functionality not supported by cells.
+Be aware that there are some features currently missing in cells, one notable
+one being security groups.  The exercises have been patched to disable
+functionality not supported by cells.
 
 
 # Local Configuration
 
-Historically DevStack has used ``localrc`` to contain all local configuration and customizations. More and more of the configuration variables available for DevStack are passed-through to the individual project configuration files.  The old mechanism for this required specific code for each file and did not scale well.  This is handled now by a master local configuration file.
+Historically DevStack has used ``localrc`` to contain all local configuration
+and customizations. More and more of the configuration variables available for
+DevStack are passed-through to the individual project configuration files.
+The old mechanism for this required specific code for each file and did not
+scale well.  This is handled now by a master local configuration file.
 
 # local.conf
 
-The new config file ``local.conf`` is an extended-INI format that introduces a new meta-section header that provides some additional information such as a phase name and destination config filename:
+The new config file ``local.conf`` is an extended-INI format that introduces
+a new meta-section header that provides some additional information such
+as a phase name and destination config filename:
 
     [[ <phase> | <config-file-name> ]]
 
@@ -339,11 +370,15 @@
 The defined phases are:
 
 * **local** - extracts ``localrc`` from ``local.conf`` before ``stackrc`` is sourced
-* **post-config** - runs after the layer 2 services are configured and before they are started
-* **extra** - runs after services are started and before any files in ``extra.d`` are executed
+* **post-config** - runs after the layer 2 services are configured
+                    and before they are started
+* **extra** - runs after services are started and before any files
+              in ``extra.d`` are executed
 * **post-extra** - runs after files in ``extra.d`` are executed
 
-The file is processed strictly in sequence; meta-sections may be specified more than once but if any settings are duplicated the last to appear in the file will be used.
+The file is processed strictly in sequence; meta-sections may be specified more
+than once but if any settings are duplicated the last to appear in the file
+will be used.
 
     [[post-config|$NOVA_CONF]]
     [DEFAULT]
diff --git a/clean.sh b/clean.sh
index 3707d84..7851da3 100755
--- a/clean.sh
+++ b/clean.sh
@@ -102,7 +102,7 @@
 fi
 
 # Clean out /etc
-sudo rm -rf /etc/keystone /etc/glance /etc/nova /etc/cinder /etc/swift
+sudo rm -rf /etc/keystone /etc/glance /etc/nova /etc/cinder /etc/swift /etc/heat /etc/neutron
 
 # Clean out tgt
 sudo rm -f /etc/tgt/conf.d/*
diff --git a/driver_certs/cinder_driver_cert.sh b/driver_certs/cinder_driver_cert.sh
index d2c636f..7726e7e 100755
--- a/driver_certs/cinder_driver_cert.sh
+++ b/driver_certs/cinder_driver_cert.sh
@@ -19,6 +19,8 @@
 #
 #     SCREEN_LOGDIR=/opt/stack/screen-logs
 
+set -o pipefail
+
 CERT_DIR=$(cd $(dirname "$0") && pwd)
 TOP_DIR=$(cd $CERT_DIR/..; pwd)
 
diff --git a/eucarc b/eucarc
index 3502351..343f4cc 100644
--- a/eucarc
+++ b/eucarc
@@ -22,7 +22,7 @@
 export EC2_URL=$(keystone catalog --service ec2 | awk '/ publicURL / { print $4 }')
 
 # Create EC2 credentials for the current user
-CREDS=$(keystone ec2-credentials-create)
+CREDS=$(openstack ec2 credentials create)
 export EC2_ACCESS_KEY=$(echo "$CREDS" | awk '/ access / { print $4 }')
 export EC2_SECRET_KEY=$(echo "$CREDS" | awk '/ secret / { print $4 }')
 
diff --git a/exercises/boot_from_volume.sh b/exercises/boot_from_volume.sh
index dff8e7a..d756685 100755
--- a/exercises/boot_from_volume.sh
+++ b/exercises/boot_from_volume.sh
@@ -44,6 +44,9 @@
 # the exercise is skipped
 is_service_enabled cinder || exit 55
 
+# Ironic does not support boot from volume.
+[ "$VIRT_DRIVER" == "ironic" ] && exit 55
+
 # Instance type to create
 DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
 
diff --git a/exercises/client-env.sh b/exercises/client-env.sh
index d955e4d..cc518d9 100755
--- a/exercises/client-env.sh
+++ b/exercises/client-env.sh
@@ -28,7 +28,7 @@
 source $TOP_DIR/functions
 
 # Import configuration
-source $TOP_DIR/openrc
+source $TOP_DIR/openrc admin
 
 # Import exercise configuration
 source $TOP_DIR/exerciserc
@@ -64,7 +64,7 @@
         STATUS_KEYSTONE="Skipped"
     else
         echo -e "\nTest Keystone"
-        if keystone catalog --service identity; then
+        if openstack endpoint show identity; then
             STATUS_KEYSTONE="Succeeded"
         else
             STATUS_KEYSTONE="Failed"
diff --git a/exercises/euca.sh b/exercises/euca.sh
index 3768b56..f9c4752 100755
--- a/exercises/euca.sh
+++ b/exercises/euca.sh
@@ -36,6 +36,9 @@
 # Import exercise configuration
 source $TOP_DIR/exerciserc
 
+# Import project functions
+source $TOP_DIR/lib/neutron
+
 # If nova api is not enabled we exit with exitcode 55 so that
 # the exercise is skipped
 is_service_enabled n-api || exit 55
@@ -82,7 +85,7 @@
 
 # Volumes
 # -------
-if is_service_enabled c-vol && ! is_service_enabled n-cell; then
+if is_service_enabled c-vol && ! is_service_enabled n-cell && [ "$VIRT_DRIVER" != "ironic" ]; then
     VOLUME_ZONE=`euca-describe-availability-zones | head -n1 | cut -f2`
     die_if_not_set $LINENO VOLUME_ZONE "Failure to find zone for volume"
 
diff --git a/exercises/floating_ips.sh b/exercises/floating_ips.sh
index 1416d4d..7e90e5a 100755
--- a/exercises/floating_ips.sh
+++ b/exercises/floating_ips.sh
@@ -180,7 +180,7 @@
 fi
 
 # FIXME (anthony): make xs support security groups
-if [ "$VIRT_DRIVER" != "xenserver" -a "$VIRT_DRIVER" != "openvz" ]; then
+if [ "$VIRT_DRIVER" != "ironic" -a "$VIRT_DRIVER" != "xenserver" -a "$VIRT_DRIVER" != "openvz" ]; then
     # Test we can aren't able to ping our floating ip within ASSOCIATE_TIMEOUT seconds
     ping_check "$PUBLIC_NETWORK_NAME" $FLOATING_IP $ASSOCIATE_TIMEOUT Fail
 fi
diff --git a/exercises/neutron-adv-test.sh b/exercises/neutron-adv-test.sh
index 0a24fe9..6679670 100755
--- a/exercises/neutron-adv-test.sh
+++ b/exercises/neutron-adv-test.sh
@@ -100,15 +100,6 @@
 DEMO1_ROUTER1_NET="demo1-net1"
 DEMO2_ROUTER1_NET="demo2-net1"
 
-KEYSTONE="keystone"
-
-# Manually create a token by querying keystone (sending JSON data).  Keystone
-# returns a token and catalog of endpoints.  We use python to parse the token
-# and save it.
-
-TOKEN=`keystone token-get | grep ' id ' | awk '{print $4}'`
-die_if_not_set $LINENO TOKEN "Keystone fail to get token"
-
 # Various functions
 # -----------------
 
@@ -150,21 +141,21 @@
 
 function get_tenant_id {
     local TENANT_NAME=$1
-    local TENANT_ID=`keystone tenant-list | grep " $TENANT_NAME " | head -n 1 | get_field 1`
+    local TENANT_ID=`openstack project list | grep " $TENANT_NAME " | head -n 1 | get_field 1`
     die_if_not_set $LINENO TENANT_ID "Failure retrieving TENANT_ID for $TENANT_NAME"
     echo "$TENANT_ID"
 }
 
 function get_user_id {
     local USER_NAME=$1
-    local USER_ID=`keystone user-list | grep $USER_NAME | awk '{print $2}'`
+    local USER_ID=`openstack user list | grep $USER_NAME | awk '{print $2}'`
     die_if_not_set $LINENO USER_ID "Failure retrieving USER_ID for $USER_NAME"
     echo "$USER_ID"
 }
 
 function get_role_id {
     local ROLE_NAME=$1
-    local ROLE_ID=`keystone role-list | grep $ROLE_NAME | awk '{print $2}'`
+    local ROLE_ID=`openstack role list | grep $ROLE_NAME | awk '{print $2}'`
     die_if_not_set $LINENO ROLE_ID "Failure retrieving ROLE_ID for $ROLE_NAME"
     echo "$ROLE_ID"
 }
@@ -199,28 +190,21 @@
 }
 
 function add_tenant {
-    local TENANT=$1
-    local USER=$2
-
-    $KEYSTONE tenant-create --name=$TENANT
-    $KEYSTONE user-create --name=$USER --pass=${ADMIN_PASSWORD}
-
-    local USER_ID=$(get_user_id $USER)
-    local TENANT_ID=$(get_tenant_id $TENANT)
-
-    $KEYSTONE user-role-add --user-id $USER_ID --role-id $(get_role_id Member) --tenant-id $TENANT_ID
+    openstack project create $1
+    openstack user create $2 --password ${ADMIN_PASSWORD} --project $1
+    openstack role add Member --project $1 --user $2
 }
 
 function remove_tenant {
     local TENANT=$1
     local TENANT_ID=$(get_tenant_id $TENANT)
-    $KEYSTONE tenant-delete $TENANT_ID
+    openstack project delete $TENANT_ID
 }
 
 function remove_user {
     local USER=$1
     local USER_ID=$(get_user_id $USER)
-    $KEYSTONE user-delete $USER_ID
+    openstack user delete $USER_ID
 }
 
 function create_tenants {
diff --git a/exercises/volumes.sh b/exercises/volumes.sh
index 0d556df..1dff6a4 100755
--- a/exercises/volumes.sh
+++ b/exercises/volumes.sh
@@ -41,6 +41,9 @@
 # exercise is skipped.
 is_service_enabled cinder || exit 55
 
+# Ironic does not currently support volume attachment.
+[ "$VIRT_DRIVER" == "ironic" ] && exit 55
+
 # Instance type to create
 DEFAULT_INSTANCE_TYPE=${DEFAULT_INSTANCE_TYPE:-m1.tiny}
 
diff --git a/extras.d/80-opendaylight.sh b/extras.d/80-opendaylight.sh
index 57b4328..bf99866 100644
--- a/extras.d/80-opendaylight.sh
+++ b/extras.d/80-opendaylight.sh
@@ -14,6 +14,7 @@
         configure_opendaylight
         init_opendaylight
     elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
+        configure_ml2_odl
         # This has to start before Neutron
         start_opendaylight
     elif [[ "$1" == "stack" && "$2" == "post-extra" ]]; then
@@ -46,7 +47,11 @@
         ODL_MGR_PORT=${ODL_MGR_PORT:-6640}
         read ovstbl <<< $(sudo ovs-vsctl get Open_vSwitch . _uuid)
         sudo ovs-vsctl set-manager tcp:$ODL_MGR_IP:$ODL_MGR_PORT
-        sudo ovs-vsctl set Open_vSwitch $ovstbl other_config={"local_ip"="$ODL_LOCAL_IP"}
+        if [[ -n "$OVS_BRIDGE_MAPPINGS" ]] && [[ "$ENABLE_TENANT_VLANS" == "True" ]]; then
+            sudo ovs-vsctl set Open_vSwitch $ovstbl \
+                other_config:bridge_mappings=$OVS_BRIDGE_MAPPINGS
+        fi
+        sudo ovs-vsctl set Open_vSwitch $ovstbl other_config:local_ip=$ODL_LOCAL_IP
     elif [[ "$1" == "stack" && "$2" == "post-extra" ]]; then
         # no-op
         :
diff --git a/files/apts/baremetal b/files/apts/baremetal
index 54e76e0..06ffab6 100644
--- a/files/apts/baremetal
+++ b/files/apts/baremetal
@@ -1,6 +1,5 @@
 busybox
 dnsmasq
-gcc
 ipmitool
 make
 open-iscsi
diff --git a/files/apts/cinder b/files/apts/cinder
index 712fee9..7819c31 100644
--- a/files/apts/cinder
+++ b/files/apts/cinder
@@ -2,6 +2,5 @@
 lvm2
 qemu-utils
 libpq-dev
-python-dev
 open-iscsi
 open-iscsi-utils # Deprecated since quantal dist:precise
diff --git a/files/apts/general b/files/apts/general
index 995c0c6..d81ec7a 100644
--- a/files/apts/general
+++ b/files/apts/general
@@ -5,6 +5,7 @@
 unzip
 wget
 psmisc
+gcc
 git
 lsof # useful when debugging
 openssh-server
@@ -18,5 +19,6 @@
 euca2ools # only for testing client
 tar
 python-cmd2 # dist:precise
+python-dev
 python2.7
 bc
diff --git a/files/apts/glance b/files/apts/glance
index 6dc878e..b5d8c77 100644
--- a/files/apts/glance
+++ b/files/apts/glance
@@ -1,11 +1,9 @@
-gcc
 libffi-dev
 libmysqlclient-dev  # testonly
 libpq-dev           # testonly
 libssl-dev          # testonly
 libxml2-dev
 libxslt1-dev        # testonly
-python-dev
 python-eventlet
 python-routes
 python-greenlet
diff --git a/files/apts/ironic b/files/apts/ironic
index a749ad7..b77a6b1 100644
--- a/files/apts/ironic
+++ b/files/apts/ironic
@@ -1,3 +1,4 @@
+iptables
 libguestfs0
 libvirt-bin
 openssh-client
diff --git a/files/apts/keystone b/files/apts/keystone
index 564921b..57fde80 100644
--- a/files/apts/keystone
+++ b/files/apts/keystone
@@ -1,4 +1,3 @@
-python-dev
 python-lxml
 python-pastescript
 python-pastedeploy
diff --git a/files/apts/n-api b/files/apts/n-api
index e0e5e7f..b4372d9 100644
--- a/files/apts/n-api
+++ b/files/apts/n-api
@@ -1,2 +1,3 @@
 python-dateutil
 msgpack-python
+fping
diff --git a/files/apts/nova b/files/apts/nova
index ae925c3..38c99c7 100644
--- a/files/apts/nova
+++ b/files/apts/nova
@@ -12,9 +12,10 @@
 ebtables
 sqlite3
 sudo
-kvm # NOPRIME
+qemu-kvm # NOPRIME
 qemu # dist:wheezy,jessie NOPRIME
 libvirt-bin # NOPRIME
+pm-utils
 libjs-jquery-tablesorter # Needed for coverage html reports
 vlan
 curl
@@ -25,7 +26,6 @@
 python-mox
 python-paste
 python-migrate
-python-gflags
 python-greenlet
 python-libvirt # NOPRIME
 python-libxml2
@@ -34,7 +34,6 @@
 python-pastedeploy
 python-eventlet
 python-cheetah
-python-carrot
 python-tempita
 python-sqlalchemy
 python-suds
diff --git a/files/apts/swift b/files/apts/swift
index 37d5bc0..080ecdb 100644
--- a/files/apts/swift
+++ b/files/apts/swift
@@ -1,10 +1,8 @@
 curl
-gcc
 libffi-dev
 memcached
 python-configobj
 python-coverage
-python-dev
 python-eventlet
 python-greenlet
 python-netifaces
diff --git a/files/apts/trema b/files/apts/trema
index 09cb7c6..f685ca5 100644
--- a/files/apts/trema
+++ b/files/apts/trema
@@ -1,5 +1,4 @@
 # Trema
-gcc
 make
 ruby1.8
 rubygems1.8
diff --git a/files/patches/unittest2-discover.patch b/files/patches/unittest2-discover.patch
new file mode 100644
index 0000000..347300d
--- /dev/null
+++ b/files/patches/unittest2-discover.patch
@@ -0,0 +1,16 @@
+diff -r b2efb7df637b discover.py
+--- a/discover.py	Thu Mar 24 00:31:02 2011 -0400
++++ b/discover.py	Thu Nov 28 12:02:19 2013 +0000
+@@ -82,7 +82,11 @@
+     """
+     testMethodPrefix = 'test'
+     sortTestMethodsUsing = cmp
+-    suiteClass = unittest.TestSuite
++    try:
++        import unittest2
++        suiteClass = unittest2.TestSuite
++    except ImportError:
++        suiteClass = unittest.TestSuite
+     _top_level_dir = None
+ 
+     def loadTestsFromTestCase(self, testCaseClass):
diff --git a/files/rpms-suse/general b/files/rpms-suse/general
index ff27a3a..82cb09d 100644
--- a/files/rpms-suse/general
+++ b/files/rpms-suse/general
@@ -3,6 +3,7 @@
 ca-certificates-mozilla
 curl
 euca2ools
+gcc
 git-core
 iputils
 libopenssl-devel # to rebuild pyOpenSSL if needed
diff --git a/files/rpms-suse/glance b/files/rpms-suse/glance
index d9844e9..edd1564 100644
--- a/files/rpms-suse/glance
+++ b/files/rpms-suse/glance
@@ -1,4 +1,3 @@
-gcc
 libxml2-devel
 python-PasteDeploy
 python-Routes
diff --git a/files/rpms-suse/n-api b/files/rpms-suse/n-api
index 0f08daa..6f59e60 100644
--- a/files/rpms-suse/n-api
+++ b/files/rpms-suse/n-api
@@ -1 +1,2 @@
 python-dateutil
+fping
diff --git a/files/rpms-suse/neutron b/files/rpms-suse/neutron
index e9ccf59..d4841b1 100644
--- a/files/rpms-suse/neutron
+++ b/files/rpms-suse/neutron
@@ -1,9 +1,9 @@
 dnsmasq
-dnsmasq-utils # dist:opensuse-12.3
+dnsmasq-utils # dist:opensuse-12.3,opensuse-13.1
 ebtables
 iptables
 iputils
-mysql-community-server # NOPRIME
+mariadb # NOPRIME
 python-boto
 python-eventlet
 python-greenlet
diff --git a/files/rpms-suse/nova b/files/rpms-suse/nova
index ee4917d..3e95724 100644
--- a/files/rpms-suse/nova
+++ b/files/rpms-suse/nova
@@ -1,6 +1,6 @@
 curl
 dnsmasq
-dnsmasq-utils # dist:opensuse-12.3
+dnsmasq-utils # dist:opensuse-12.3,opensuse-13.1
 ebtables
 gawk
 genisoimage # required for config_drive
@@ -12,8 +12,7 @@
 qemu # NOPRIME
 libvirt # NOPRIME
 libvirt-python # NOPRIME
-libxml2-python
-mysql-community-server # NOPRIME
+mariadb # NOPRIME
 parted
 polkit
 python-M2Crypto
@@ -24,20 +23,19 @@
 python-SQLAlchemy
 python-Tempita
 python-boto
-python-carrot
 python-cheetah
 python-eventlet
 python-feedparser
 python-greenlet
 python-iso8601
 python-kombu
+python-libxml2
 python-lockfile
 python-lxml # needed for glance which is needed for nova --- this shouldn't be here
 python-mox
 python-mysql
 python-numpy # needed by websockify for spice console
 python-paramiko
-python-python-gflags
 python-sqlalchemy-migrate
 python-suds
 python-xattr # needed for glance which is needed for nova --- this shouldn't be here
diff --git a/files/rpms-suse/opendaylight b/files/rpms-suse/opendaylight
index d6c7146..f7fafff 100644
--- a/files/rpms-suse/opendaylight
+++ b/files/rpms-suse/opendaylight
@@ -1,4 +1,3 @@
 openvswitch # NOPRIME
-openvswitch-controller # NOPRIME
 openvswitch-switch # NOPRIME
 
diff --git a/files/rpms-suse/swift b/files/rpms-suse/swift
index f3c95aa..4b14098 100644
--- a/files/rpms-suse/swift
+++ b/files/rpms-suse/swift
@@ -1,5 +1,4 @@
 curl
-gcc
 memcached
 python-PasteDeploy
 python-WebOb
diff --git a/files/rpms/cinder b/files/rpms/cinder
index 423d57c..ce6181e 100644
--- a/files/rpms/cinder
+++ b/files/rpms/cinder
@@ -1,7 +1,6 @@
 lvm2
 scsi-target-utils
 qemu-img
-python-devel
 postgresql-devel
 iscsi-initiator-utils
 python-lxml         #dist:f19,f20,rhel7
diff --git a/files/rpms/general b/files/rpms/general
index 6cfe31e..c940de6 100644
--- a/files/rpms/general
+++ b/files/rpms/general
@@ -2,19 +2,20 @@
 curl
 dbus
 euca2ools # only for testing client
-gcc # dist:rhel6 [2]
+gcc
 git-core
 openssh-server
 openssl
 openssl-devel # to rebuild pyOpenSSL if needed
-libxml2-devel # dist:rhel6 [2]
-libxslt-devel # dist:rhel6 [2]
+libxml2-devel
+libxslt-devel
 psmisc
 pylint
 python-setuptools
 python-prettytable # dist:rhel6 [1]
 python-unittest2
 python-virtualenv
+python-devel
 screen
 tar
 tcpdump
@@ -27,7 +28,3 @@
 # but others have versioned (<=0.7).  So if a later version (0.7.1)
 # gets installed in response to an unversioned dependency, it breaks.
 # This pre-installs a compatible 0.6(ish) version from RHEL
-
-# [2] : RHEL6 rpm versions of python-lxml is old, and has to be
-# removed.  Several tools rely on it, so we install the dependencies
-# pip needs to build it here (see tools/install_prereqs.sh)
diff --git a/files/rpms/glance b/files/rpms/glance
index 2007e2e..fc07fa7 100644
--- a/files/rpms/glance
+++ b/files/rpms/glance
@@ -1,4 +1,3 @@
-gcc
 libffi-devel
 libxml2-devel       # testonly
 libxslt-devel       # testonly
@@ -6,7 +5,6 @@
 openssl-devel       # testonly
 postgresql-devel    # testonly
 python-argparse
-python-devel
 python-eventlet
 python-greenlet
 python-lxml         #dist:f19,f20,rhel7
diff --git a/files/rpms/horizon b/files/rpms/horizon
index 2dd24e0..92afed2 100644
--- a/files/rpms/horizon
+++ b/files/rpms/horizon
@@ -1,6 +1,4 @@
 Django
-django-registration
-gcc
 httpd # NOPRIME
 mod_wsgi  # NOPRIME
 pylint
diff --git a/files/rpms/ironic b/files/rpms/ironic
index 54b9829..6534095 100644
--- a/files/rpms/ironic
+++ b/files/rpms/ironic
@@ -1,6 +1,8 @@
+iptables
 libguestfs
 libvirt
 libvirt-python
+net-tools
 openssh-clients
 openvswitch
 python-libguestfs
diff --git a/files/rpms/n-api b/files/rpms/n-api
index 0f08daa..6f59e60 100644
--- a/files/rpms/n-api
+++ b/files/rpms/n-api
@@ -1 +1,2 @@
 python-dateutil
+fping
diff --git a/files/rpms/neutron b/files/rpms/neutron
index 06ea0ea..9fafecb 100644
--- a/files/rpms/neutron
+++ b/files/rpms/neutron
@@ -21,4 +21,3 @@
 qpid-cpp-server        # NOPRIME
 sqlite
 sudo
-vconfig
diff --git a/files/rpms/nova b/files/rpms/nova
index 45d6e0b..e05d0d7 100644
--- a/files/rpms/nova
+++ b/files/rpms/nova
@@ -17,11 +17,9 @@
 parted
 polkit
 python-boto
-python-carrot
 python-cheetah
 python-eventlet
 python-feedparser
-python-gflags
 python-greenlet
 python-iso8601
 python-kombu
@@ -42,4 +40,3 @@
 qpid-cpp-server # NOPRIME
 sqlite
 sudo
-vconfig
diff --git a/files/rpms/swift b/files/rpms/swift
index bf29ea2..938d2c8 100644
--- a/files/rpms/swift
+++ b/files/rpms/swift
@@ -1,10 +1,8 @@
 curl
-gcc
 libffi-devel
 memcached
 python-configobj
 python-coverage
-python-devel
 python-eventlet
 python-greenlet
 python-netifaces
diff --git a/functions b/functions
index 17c6e77..80f98ad 100644
--- a/functions
+++ b/functions
@@ -199,7 +199,21 @@
     # and should not be decompressed prior to loading
     if [[ "$image_url" =~ '.vhd.tgz' ]]; then
         IMAGE_NAME="${IMAGE_FNAME%.vhd.tgz}"
-        glance --os-auth-token $token --os-image-url http://$GLANCE_HOSTPORT image-create --name "$IMAGE_NAME" --is-public=True --container-format=ovf --disk-format=vhd < "${IMAGE}"
+        FORCE_VM_MODE=""
+        if [[ "$IMAGE_NAME" =~ 'cirros' ]]; then
+            # Cirros VHD image currently only boots in PV mode.
+            # Nova defaults to PV for all VHD images, but
+            # the glance setting is needed for booting
+            # directly from volume.
+            FORCE_VM_MODE="--property vm_mode=xen"
+        fi
+        glance \
+            --os-auth-token $token \
+            --os-image-url http://$GLANCE_HOSTPORT \
+            image-create \
+            --name "$IMAGE_NAME" --is-public=True \
+            --container-format=ovf --disk-format=vhd \
+            $FORCE_VM_MODE < "${IMAGE}"
         return
     fi
 
diff --git a/functions-common b/functions-common
index c6fd5c7..cc90c07 100644
--- a/functions-common
+++ b/functions-common
@@ -824,6 +824,10 @@
             if [[ ! $file_to_parse =~ neutron ]]; then
                 file_to_parse="${file_to_parse} neutron"
             fi
+        elif [[ $service == ir-* ]]; then
+            if [[ ! $file_to_parse =~ ironic ]]; then
+                file_to_parse="${file_to_parse} ironic"
+            fi
         fi
     done
 
@@ -1227,14 +1231,27 @@
 
     $xtrace
     $SUDO_PIP PIP_DOWNLOAD_CACHE=${PIP_DOWNLOAD_CACHE:-/var/cache/pip} \
-        HTTP_PROXY=$http_proxy \
-        HTTPS_PROXY=$https_proxy \
-        NO_PROXY=$no_proxy \
+        http_proxy=$http_proxy \
+        https_proxy=$https_proxy \
+        no_proxy=$no_proxy \
         $CMD_PIP install --build=${pip_build_tmp} \
         $PIP_MIRROR_OPT $@ \
         && $SUDO_PIP rm -rf ${pip_build_tmp}
 }
 
+# this should be used if you want to install globally, all libraries should
+# use this, especially *oslo* ones
+function setup_install {
+    local project_dir=$1
+    setup_package_with_req_sync $project_dir
+}
+
+# this should be used for projects which run services, like all services
+function setup_develop {
+    local project_dir=$1
+    setup_package_with_req_sync $project_dir -e
+}
+
 # ``pip install -e`` the package, which processes the dependencies
 # using pip before running `setup.py develop`
 #
@@ -1243,8 +1260,9 @@
 #
 # Uses globals ``TRACK_DEPENDS``, ``REQUIREMENTS_DIR``, ``UNDO_REQUIREMENTS``
 # setup_develop directory
-function setup_develop {
+function setup_package_with_req_sync {
     local project_dir=$1
+    local flags=$2
 
     # Don't update repo if local changes exist
     # Don't use buggy "git diff --quiet"
@@ -1256,7 +1274,7 @@
             $SUDO_CMD python update.py $project_dir)
     fi
 
-    setup_develop_no_requirements_update $project_dir
+    setup_package $project_dir $flags
 
     # We've just gone and possibly modified the user's source tree in an
     # automated way, which is considered bad form if it's a development
@@ -1277,12 +1295,15 @@
 # using pip before running `setup.py develop`
 # Uses globals ``STACK_USER``
 # setup_develop_no_requirements_update directory
-function setup_develop_no_requirements_update {
+function setup_package {
     local project_dir=$1
+    local flags=$2
 
-    pip_install -e $project_dir
+    pip_install $flags $project_dir
     # ensure that further actions can do things like setup.py sdist
-    safe_chown -R $STACK_USER $1/*.egg-info
+    if [[ "$flags" == "-e" ]]; then
+        safe_chown -R $STACK_USER $1/*.egg-info
+    fi
 }
 
 
diff --git a/lib/baremetal b/lib/baremetal
index eda92f9..adcbe4c 100644
--- a/lib/baremetal
+++ b/lib/baremetal
@@ -129,7 +129,7 @@
 
 # Below this, we set some path and filenames.
 # Defaults are probably sufficient.
-BM_IMAGE_BUILD_DIR=${BM_IMAGE_BUILD_DIR:-$DEST/diskimage-builder}
+DIB_DIR=${DIB_DIR:-$DEST/diskimage-builder}
 
 # Use DIB to create deploy ramdisk and kernel.
 BM_BUILD_DEPLOY_RAMDISK=`trueorfalse True $BM_BUILD_DEPLOY_RAMDISK`
@@ -165,7 +165,7 @@
 # Install diskimage-builder and shell-in-a-box
 # so that we can build the deployment kernel & ramdisk
 function prepare_baremetal_toolchain {
-    git_clone $BM_IMAGE_BUILD_REPO $BM_IMAGE_BUILD_DIR $BM_IMAGE_BUILD_BRANCH
+    git_clone $DIB_REPO $DIB_DIR $DIB_BUILD_BRANCH
 
     local shellinabox_basename=$(basename $BM_SHELL_IN_A_BOX)
     if [[ ! -e $DEST/$shellinabox_basename ]]; then
@@ -223,7 +223,7 @@
         BM_DEPLOY_KERNEL=bm-deploy.kernel
         BM_DEPLOY_RAMDISK=bm-deploy.initramfs
         if [ ! -e "$TOP_DIR/files/$BM_DEPLOY_KERNEL" -o ! -e "$TOP_DIR/files/$BM_DEPLOY_RAMDISK" ]; then
-            $BM_IMAGE_BUILD_DIR/bin/ramdisk-image-create $BM_DEPLOY_FLAVOR \
+            $DIB_DIR/bin/ramdisk-image-create $BM_DEPLOY_FLAVOR \
                 -o $TOP_DIR/files/bm-deploy
         fi
     fi
@@ -271,7 +271,7 @@
     image_name=$(basename "$file" ".qcow2")
 
     # this call returns the file names as "$kernel,$ramdisk"
-    out=$($BM_IMAGE_BUILD_DIR/bin/disk-image-get-kernel \
+    out=$($DIB_DIR/bin/disk-image-get-kernel \
             -x -d $TOP_DIR/files -o bm-deploy -i $file)
     if [ $? -ne 0 ]; then
         die $LINENO "Failed to get kernel and ramdisk from $file"
diff --git a/lib/ceilometer b/lib/ceilometer
index 5030b3c..a4be7af 100644
--- a/lib/ceilometer
+++ b/lib/ceilometer
@@ -147,18 +147,22 @@
 
     # Install the policy file for the API server
     cp $CEILOMETER_DIR/etc/ceilometer/policy.json $CEILOMETER_CONF_DIR
-    cp $CEILOMETER_DIR/etc/ceilometer/pipeline.yaml $CEILOMETER_CONF_DIR
     iniset $CEILOMETER_CONF DEFAULT policy_file $CEILOMETER_CONF_DIR/policy.json
 
+    cp $CEILOMETER_DIR/etc/ceilometer/pipeline.yaml $CEILOMETER_CONF_DIR
+    cp $CEILOMETER_DIR/etc/ceilometer/api_paste.ini $CEILOMETER_CONF_DIR
+    cp $CEILOMETER_DIR/etc/ceilometer/event_definitions.yaml $CEILOMETER_CONF_DIR
+
     if [ "$CEILOMETER_PIPELINE_INTERVAL" ]; then
         sed -i "s/interval:.*/interval: ${CEILOMETER_PIPELINE_INTERVAL}/" $CEILOMETER_CONF_DIR/pipeline.yaml
     fi
 
     # the compute and central agents need these credentials in order to
-    # call out to the public nova and glance APIs
-    iniset $CEILOMETER_CONF DEFAULT os_username ceilometer
-    iniset $CEILOMETER_CONF DEFAULT os_password $SERVICE_PASSWORD
-    iniset $CEILOMETER_CONF DEFAULT os_tenant_name $SERVICE_TENANT_NAME
+    # call out to other services' public APIs
+    # the alarm evaluator needs these options to call ceilometer APIs
+    iniset $CEILOMETER_CONF service_credentials os_username ceilometer
+    iniset $CEILOMETER_CONF service_credentials os_password $SERVICE_PASSWORD
+    iniset $CEILOMETER_CONF service_credentials os_tenant_name $SERVICE_TENANT_NAME
 
     iniset $CEILOMETER_CONF keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
     iniset $CEILOMETER_CONF keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
@@ -236,7 +240,7 @@
 # start_ceilometer() - Start running processes, including screen
 function start_ceilometer {
     if [[ "$VIRT_DRIVER" = 'libvirt' ]]; then
-        screen_it ceilometer-acompute "cd ; sg $LIBVIRT_GROUP \"ceilometer-agent-compute --config-file $CEILOMETER_CONF\""
+        screen_it ceilometer-acompute "cd ; sg $LIBVIRT_GROUP 'ceilometer-agent-compute --config-file $CEILOMETER_CONF'"
     fi
     if [[ "$VIRT_DRIVER" = 'vsphere' ]]; then
         screen_it ceilometer-acompute "cd ; ceilometer-agent-compute --config-file $CEILOMETER_CONF"
diff --git a/lib/cinder b/lib/cinder
index dd2956a..dadbe40 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -274,6 +274,10 @@
     iniset $CINDER_CONF DEFAULT lock_path $CINDER_STATE_PATH
     iniset $CINDER_CONF DEFAULT periodic_interval $CINDER_PERIODIC_INTERVAL
 
+    if is_service_enabled swift; then
+        iniset $CINDER_CONF DEFAULT backup_swift_url "http://$SERVICE_HOST:8080/v1/AUTH_"
+    fi
+
     if is_service_enabled ceilometer; then
         iniset $CINDER_CONF DEFAULT notification_driver "cinder.openstack.common.notifier.rpc_notifier"
     fi
diff --git a/lib/cinder_plugins/nfs b/lib/cinder_plugins/nfs
index 2d9d875..5f4cc53 100644
--- a/lib/cinder_plugins/nfs
+++ b/lib/cinder_plugins/nfs
@@ -30,8 +30,7 @@
 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
+    echo "$CINDER_NFS_SERVERPATH" | tee "$CINDER_CONF_DIR/nfs_shares.conf"
 }
 
 # Restore xtrace
diff --git a/lib/databases/mysql b/lib/databases/mysql
index 7a0145a..ea22d14 100644
--- a/lib/databases/mysql
+++ b/lib/databases/mysql
@@ -47,6 +47,7 @@
 }
 
 function configure_database_mysql {
+    local slow_log
     echo_summary "Configuring and starting MySQL"
 
     if is_ubuntu; then
@@ -83,36 +84,32 @@
 
     # Now update ``my.cnf`` for some local needs and restart the mysql service
 
-    # Change ‘bind-address’ from localhost (127.0.0.1) to any (0.0.0.0)
-    sudo sed -i '/^bind-address/s/127.0.0.1/0.0.0.0/g' $MY_CONF
+    # Change ‘bind-address’ from localhost (127.0.0.1) to any (0.0.0.0) and
+    # set default db type to InnoDB
+    sudo bash -c "source $TOP_DIR/functions && \
+        iniset $MY_CONF mysqld bind-address 0.0.0.0 && \
+        iniset $MY_CONF mysqld default-storage-engine InnoDB"
 
-    # Set default db type to InnoDB
-    if sudo grep -q "default-storage-engine" $MY_CONF; then
-        # Change it
-        sudo bash -c "source $TOP_DIR/functions; iniset $MY_CONF mysqld default-storage-engine InnoDB"
-    else
-        # Add it
-        sudo sed -i -e "/^\[mysqld\]/ a \
-default-storage-engine = InnoDB" $MY_CONF
-    fi
 
     if [[ "$DATABASE_QUERY_LOGGING" == "True" ]]; then
         echo_summary "Enabling MySQL query logging"
+        if is_fedora && ! [[ $DISTRO =~ (rhel6) ]]; then
+            slow_log=/var/log/mariadb/mariadb-slow.log
+        else
+            slow_log=/var/log/mysql/mysql-slow.log
+        fi
+        sudo sed -e '/log.slow.queries/d' \
+            -e '/long.query.time/d' \
+            -e '/log.queries.not.using.indexes/d' \
+            -i $MY_CONF
 
-        # Turn on slow query log
-        sudo sed -i '/log.slow.queries/d' $MY_CONF
-        sudo sed -i -e "/^\[mysqld\]/ a \
-            log-slow-queries = /var/log/mysql/mysql-slow.log" $MY_CONF
-
-        # Log all queries (any query taking longer than 0 seconds)
-        sudo sed -i '/long.query.time/d' $MY_CONF
-        sudo sed -i -e "/^\[mysqld\]/ a \
-            long-query-time = 0" $MY_CONF
-
-        # Log all non-indexed queries
-        sudo sed -i '/log.queries.not.using.indexes/d' $MY_CONF
-        sudo sed -i -e "/^\[mysqld\]/ a \
-            log-queries-not-using-indexes" $MY_CONF
+        # Turn on slow query log, log all queries (any query taking longer than
+        # 0 seconds) and log all non-indexed queries
+        sudo bash -c "source $TOP_DIR/functions && \
+            iniset $MY_CONF mysqld slow-query-log 1 && \
+            iniset $MY_CONF mysqld slow-query-log-file $slow_log && \
+            iniset $MY_CONF mysqld long-query-time 0 && \
+            iniset $MY_CONF mysqld log-queries-not-using-indexes 1"
 
     fi
 
diff --git a/lib/heat b/lib/heat
index 902333e..fe75ec9 100644
--- a/lib/heat
+++ b/lib/heat
@@ -37,6 +37,10 @@
 HEAT_CONF=$HEAT_CONF_DIR/heat.conf
 HEAT_ENV_DIR=$HEAT_CONF_DIR/environment.d
 HEAT_TEMPLATES_DIR=$HEAT_CONF_DIR/templates
+HEAT_STACK_DOMAIN=`trueorfalse True $HEAT_STACK_DOMAIN`
+
+# other default options
+HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-trusts}
 
 # Tell Tempest this project is present
 TEMPEST_SERVICES+=,heat
@@ -92,7 +96,7 @@
     iniset $HEAT_CONF DEFAULT heat_waitcondition_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1/waitcondition
     iniset $HEAT_CONF DEFAULT heat_watch_server_url http://$HEAT_API_CW_HOST:$HEAT_API_CW_PORT
     iniset $HEAT_CONF database connection `database_connection_url heat`
-    iniset $HEAT_CONF DEFAULT auth_encryption_key `hexdump -n 16 -v -e '/1 "%02x"' /dev/random`
+    iniset $HEAT_CONF DEFAULT auth_encryption_key `hexdump -n 16 -v -e '/1 "%02x"' /dev/urandom`
 
     # logging
     iniset $HEAT_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
@@ -115,7 +119,6 @@
 
     # ec2authtoken
     iniset $HEAT_CONF ec2authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0
-    iniset $HEAT_CONF ec2authtoken keystone_ec2_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0/ec2tokens
 
     # paste_deploy
     [[ "$HEAT_STANDALONE" = "True" ]] && iniset $HEAT_CONF paste_deploy flavor standalone
@@ -247,37 +250,42 @@
     # heat_stack_user role is for users created by Heat
     openstack role create heat_stack_user
 
-    # heat_stack_owner role is given to users who create Heat stacks,
-    # it's the default role used by heat to delegate to the heat service
-    # user (for performing deferred operations via trusts), see heat.conf
-    HEAT_OWNER_ROLE=$(openstack role create \
-        heat_stack_owner \
-        | grep " id " | get_field 2)
+    if [[ $HEAT_DEFERRED_AUTH == trusts ]]; then
+        # heat_stack_owner role is given to users who create Heat stacks,
+        # it's the default role used by heat to delegate to the heat service
+        # user (for performing deferred operations via trusts), see heat.conf
+        HEAT_OWNER_ROLE=$(openstack role create \
+            heat_stack_owner \
+            | grep " id " | get_field 2)
 
-    # Give the role to the demo and admin users so they can create stacks
-    # in either of the projects created by devstack
-    openstack role add $HEAT_OWNER_ROLE --project demo --user demo
-    openstack role add $HEAT_OWNER_ROLE --project demo --user admin
-    openstack role add $HEAT_OWNER_ROLE --project admin --user admin
+        # Give the role to the demo and admin users so they can create stacks
+        # in either of the projects created by devstack
+        openstack role add $HEAT_OWNER_ROLE --project demo --user demo
+        openstack role add $HEAT_OWNER_ROLE --project demo --user admin
+        openstack role add $HEAT_OWNER_ROLE --project admin --user admin
+        iniset $HEAT_CONF DEFAULT deferred_auth_method trusts
+    fi
 
-    # Note we have to pass token/endpoint here because the current endpoint and
-    # version negotiation in OSC means just --os-identity-api-version=3 won't work
-    KS_ENDPOINT_V3="$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v3"
-    D_ID=$(openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
-        --os-identity-api-version=3 domain create heat \
-        --description "Owns users and projects created by heat" \
-        | grep ' id ' | get_field 2)
-    iniset $HEAT_CONF DEFAULT stack_user_domain ${D_ID}
+    if [[ "$HEAT_STACK_DOMAIN" == "True" ]]; then
+        # Note we have to pass token/endpoint here because the current endpoint and
+        # version negotiation in OSC means just --os-identity-api-version=3 won't work
+        KS_ENDPOINT_V3="$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v3"
+        D_ID=$(openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
+            --os-identity-api-version=3 domain create heat \
+            --description "Owns users and projects created by heat" \
+            | grep ' id ' | get_field 2)
+        iniset $HEAT_CONF DEFAULT stack_user_domain ${D_ID}
 
-    openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
-        --os-identity-api-version=3 user create --password $SERVICE_PASSWORD \
-        --domain $D_ID heat_domain_admin \
-        --description "Manages users and projects created by heat"
-    openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
-        --os-identity-api-version=3 role add \
-        --user heat_domain_admin --domain ${D_ID} admin
-    iniset $HEAT_CONF DEFAULT stack_domain_admin heat_domain_admin
-    iniset $HEAT_CONF DEFAULT stack_domain_admin_password $SERVICE_PASSWORD
+        openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
+            --os-identity-api-version=3 user create --password $SERVICE_PASSWORD \
+            --domain $D_ID heat_domain_admin \
+            --description "Manages users and projects created by heat"
+        openstack --os-token $OS_TOKEN --os-url=$KS_ENDPOINT_V3 \
+            --os-identity-api-version=3 role add \
+            --user heat_domain_admin --domain ${D_ID} admin
+        iniset $HEAT_CONF DEFAULT stack_domain_admin heat_domain_admin
+        iniset $HEAT_CONF DEFAULT stack_domain_admin_password $SERVICE_PASSWORD
+    fi
 }
 
 # Restore xtrace
diff --git a/lib/horizon b/lib/horizon
index 27c2d26..9ce4853 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -45,7 +45,10 @@
     local option=$3
     local value=$4
 
-    if grep -q "^$section" $file; then
+    if [ -z "$section" ]; then
+        sed -e "/^$option/d" -i $local_settings
+        echo -e "\n$option=$value" >> $file
+    elif grep -q "^$section" $file; then
         line=$(sed -ne "/^$section/,/^}/ { /^ *'$option':/ p; }" $file)
         if [ -n "$line" ]; then
             sed -i -e "/^$section/,/^}/ s/^\( *'$option'\) *:.*$/\1: $value,/" $file
@@ -103,6 +106,13 @@
         _horizon_config_set $local_settings OPENSTACK_NEUTRON_NETWORK enable_vpn True
     fi
 
+    _horizon_config_set $local_settings "" OPENSTACK_HOST \"${KEYSTONE_SERVICE_HOST}\"
+    _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_URL "\"${KEYSTONE_SERVICE_PROTOCOL}://%s:${KEYSTONE_SERVICE_PORT}/v2.0\" % OPENSTACK_HOST"
+
+    if [ -f $SSL_BUNDLE_FILE ]; then
+        _horizon_config_set $local_settings "" OPENSTACK_SSL_CACERT \"${SSL_BUNDLE_FILE}\"
+    fi
+
     # Create an empty directory that apache uses as docroot
     sudo mkdir -p $HORIZON_DIR/.blackhole
 
@@ -114,11 +124,9 @@
 
     local horizon_conf=/etc/$APACHE_NAME/$APACHE_CONF_DIR/horizon.conf
     if is_ubuntu; then
-        # Clean up the old config name
-        sudo rm -f /etc/apache2/sites-enabled/000-default
-        # Be a good citizen and use the distro tools here
+        disable_apache_site 000-default
         sudo touch $horizon_conf
-        sudo a2ensite horizon.conf
+        enable_apache_site horizon.conf
     elif is_fedora; then
         sudo sed '/^Listen/s/^.*$/Listen 0.0.0.0:80/' -i /etc/httpd/conf/httpd.conf
     elif is_suse; then
diff --git a/lib/infra b/lib/infra
index 7f70ff2..e2f7dad 100644
--- a/lib/infra
+++ b/lib/infra
@@ -46,7 +46,7 @@
 
     # Install pbr
     git_clone $PBR_REPO $PBR_DIR $PBR_BRANCH
-    setup_develop $PBR_DIR
+    setup_install $PBR_DIR
 }
 
 # Restore xtrace
diff --git a/lib/ironic b/lib/ironic
index c6fa563..389040c 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -42,24 +42,48 @@
 IRONIC_SCRIPTS_DIR=${IRONIC_SCRIPTS_DIR:-$TOP_DIR/tools/ironic/scripts}
 IRONIC_TEMPLATES_DIR=${IRONIC_TEMPLATES_DIR:-$TOP_DIR/tools/ironic/templates}
 IRONIC_BAREMETAL_BASIC_OPS=$(trueorfalse False $IRONIC_BAREMETAL_BASIC_OPS)
+IRONIC_ENABLED_DRIVERS=${IRONIC_ENABLED_DRIVERS:-fake,pxe_ssh,pxe_ipmitool}
 IRONIC_SSH_USERNAME=${IRONIC_SSH_USERNAME:-`whoami`}
 IRONIC_SSH_KEY_DIR=${IRONIC_SSH_KEY_DIR:-$IRONIC_DATA_DIR/ssh_keys}
 IRONIC_SSH_KEY_FILENAME=${IRONIC_SSH_KEY_FILENAME:-ironic_key}
 IRONIC_KEY_FILE=$IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME
 IRONIC_SSH_VIRT_TYPE=${IRONIC_SSH_VIRT_TYPE:-virsh}
 IRONIC_TFTPBOOT_DIR=${IRONIC_TFTPBOOT_DIR:-$IRONIC_DATA_DIR/tftpboot}
-IRONIC_VM_SSH_PORT=${IRONIC_VM_SSH_PORT:-2222}
+IRONIC_VM_SSH_PORT=${IRONIC_VM_SSH_PORT:-22}
 IRONIC_VM_SSH_ADDRESS=${IRONIC_VM_SSH_ADDRESS:-$HOST_IP}
 IRONIC_VM_COUNT=${IRONIC_VM_COUNT:-1}
 IRONIC_VM_SPECS_CPU=${IRONIC_VM_SPECS_CPU:-1}
-IRONIC_VM_SPECS_RAM=${IRONIC_VM_SPECS_RAM:-256}
+# NOTE(adam_g): Kernels 3.12 and newer user tmpfs by default for initramfs.
+#               DIB produced ramdisks tend to be ~250MB but tmpfs will only allow
+#               use of 50% of available memory before ENOSPC.  Set minimum 1GB
+#               for nodes to avoid (LP: #1311987) and ensure consistency across
+#               older and newer kernels.
+IRONIC_VM_SPECS_RAM=${IRONIC_VM_SPECS_RAM:-1024}
 IRONIC_VM_SPECS_DISK=${IRONIC_VM_SPECS_DISK:-10}
+IRONIC_VM_EPHEMERAL_DISK=${IRONIC_VM_EPHEMERAL_DISK:-0}
 IRONIC_VM_EMULATOR=${IRONIC_VM_EMULATOR:-/usr/bin/qemu-system-x86_64}
 IRONIC_VM_NETWORK_BRIDGE=${IRONIC_VM_NETWORK_BRIDGE:-brbm}
 IRONIC_VM_NETWORK_RANGE=${IRONIC_VM_NETWORK_RANGE:-192.0.2.0/24}
 IRONIC_VM_MACS_CSV_FILE=${IRONIC_VM_MACS_CSV_FILE:-$IRONIC_DATA_DIR/ironic_macs.csv}
 IRONIC_AUTHORIZED_KEYS_FILE=${IRONIC_AUTHORIZED_KEYS_FILE:-$HOME/.ssh/authorized_keys}
 
+# By default, baremetal VMs will console output to file.
+IRONIC_VM_LOG_CONSOLE=${IRONIC_VM_LOG_CONSOLE:-True}
+IRONIC_VM_LOG_DIR=${IRONIC_VM_LOG_DIR:-$IRONIC_DATA_DIR/logs/}
+
+DIB_DIR=${DIB_DIR:-$DEST/diskimage-builder}
+
+# Use DIB to create deploy ramdisk and kernel.
+IRONIC_BUILD_DEPLOY_RAMDISK=`trueorfalse True $IRONIC_BUILD_DEPLOY_RAMDISK`
+# If not use DIB, these files are used as deploy ramdisk/kernel.
+# (The value must be a absolute path)
+IRONIC_DEPLOY_RAMDISK=${IRONIC_DEPLOY_RAMDISK:-}
+IRONIC_DEPLOY_KERNEL=${IRONIC_DEPLOY_KERNEL:-}
+IRONIC_DEPLOY_ELEMENT=${IRONIC_DEPLOY_ELEMENT:-deploy-ironic}
+
+#TODO(agordeev): replace 'ubuntu' with host distro name getting
+IRONIC_DEPLOY_FLAVOR=${IRONIC_DEPLOY_FLAVOR:-ubuntu $IRONIC_DEPLOY_ELEMENT}
+
 # Support entry points installation of console scripts
 IRONIC_BIN_DIR=$(get_python_exec_prefix)
 
@@ -152,12 +176,25 @@
 function configure_ironic_conductor {
     cp $IRONIC_DIR/etc/ironic/rootwrap.conf $IRONIC_ROOTWRAP_CONF
     cp -r $IRONIC_DIR/etc/ironic/rootwrap.d $IRONIC_CONF_DIR
+    IRONIC_ROOTWRAP=$(get_rootwrap_location ironic)
+    ROOTWRAP_ISUDOER_CMD="$IRONIC_ROOTWRAP $IRONIC_CONF_DIR/rootwrap.conf *"
+
+    # Set up the rootwrap sudoers for ironic
+    TEMPFILE=`mktemp`
+    echo "$STACK_USER ALL=(root) NOPASSWD: $ROOTWRAP_ISUDOER_CMD" >$TEMPFILE
+    chmod 0440 $TEMPFILE
+    sudo chown root:root $TEMPFILE
+    sudo mv $TEMPFILE /etc/sudoers.d/ironic-rootwrap
 
     iniset $IRONIC_CONF_FILE DEFAULT rootwrap_config $IRONIC_ROOTWRAP_CONF
-    iniset $IRONIC_CONF_FILE conductor api_url http://$SERVICE_HOST:6385
-    iniset $IRONIC_CONF_FILE pxe tftp_server $SERVICE_HOST
+    iniset $IRONIC_CONF_FILE DEFAULT enabled_drivers $IRONIC_ENABLED_DRIVERS
+    iniset $IRONIC_CONF_FILE conductor api_url http://$HOST_IP:6385
+    iniset $IRONIC_CONF_FILE pxe tftp_server $HOST_IP
     iniset $IRONIC_CONF_FILE pxe tftp_root $IRONIC_TFTPBOOT_DIR
     iniset $IRONIC_CONF_FILE pxe tftp_master_path $IRONIC_TFTPBOOT_DIR/master_images
+    if [[ "$IRONIC_VM_LOG_CONSOLE" == "True" ]] ; then
+        iniset $IRONIC_CONF_FILE pxe pxe_append_params "nofb nomodeset vga=normal console=ttyS0"
+    fi
 }
 
 # create_ironic_cache_dir() - Part of the init_ironic() process
@@ -284,20 +321,18 @@
     mkdir -p $IRONIC_TFTPBOOT_DIR/pxelinux.cfg
 }
 
-function ironic_ensure_libvirt_group {
-    groups $STACK_USER | grep -q $LIBVIRT_GROUP || adduser $STACK_USER $LIBVIRT_GROUP
-}
-
 function create_bridge_and_vms {
-    ironic_ensure_libvirt_group
-
     # Call libvirt setup scripts in a new shell to ensure any new group membership
     sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/setup-network"
-
+    if [[ "$IRONIC_VM_LOG_CONSOLE" == "True" ]] ; then
+        LOG_ARG="$IRONIC_VM_LOG_DIR"
+    else
+        LOG_ARG=""
+    fi
     sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/create-nodes \
         $IRONIC_VM_SPECS_CPU $IRONIC_VM_SPECS_RAM $IRONIC_VM_SPECS_DISK \
-        amd64 $IRONIC_VM_COUNT $IRONIC_VM_NETWORK_BRIDGE $IRONIC_VM_EMULATOR" >> $IRONIC_VM_MACS_CSV_FILE
-
+        amd64 $IRONIC_VM_COUNT $IRONIC_VM_NETWORK_BRIDGE $IRONIC_VM_EMULATOR \
+        $LOG_ARG" >> $IRONIC_VM_MACS_CSV_FILE
 }
 
 function enroll_vms {
@@ -306,8 +341,13 @@
     IRONIC_NET_ID=$(neutron net-list | grep private | get_field 1)
     local idx=0
 
-    # work around; need to know what netns neutron uses for private network
-    neutron port-create private
+    # work around; need to know what netns neutron uses for private network.
+    # Without knowing how to interconnect the networks, PXE won't work properly
+    # for fake baremetal instances. The network should be configured prior all
+    # the instances operation. If we don't do this, the first port creation
+    # only happens in the middle of fake baremetal instance's spawning by nova,
+    # so we'll end up with unbootable fake baremetal VM due to broken PXE.
+    PORT_ID=$(neutron port-create private | grep " id " | get_field 2)
 
     while read MAC; do
 
@@ -330,8 +370,9 @@
     done < $IRONIC_VM_MACS_CSV_FILE
 
     # create the nova flavor
-    nova flavor-create baremetal auto $IRONIC_VM_SPECS_RAM $IRONIC_VM_SPECS_DISK $IRONIC_VM_SPECS_CPU
-    nova flavor-key baremetal set "cpu_arch"="x86_64" "baremetal:deploy_kernel_id"="$BM_DEPLOY_KERNEL_ID" "baremetal:deploy_ramdisk_id"="$BM_DEPLOY_RAMDISK_ID"
+    adjusted_disk=$(($IRONIC_VM_SPECS_DISK - $IRONIC_VM_EPHEMERAL_DISK))
+    nova flavor-create --ephemeral $IRONIC_VM_EPHEMERAL_DISK baremetal auto $IRONIC_VM_SPECS_RAM $adjusted_disk $IRONIC_VM_SPECS_CPU
+    nova flavor-key baremetal set "cpu_arch"="x86_64" "baremetal:deploy_kernel_id"="$IRONIC_DEPLOY_KERNEL_ID" "baremetal:deploy_ramdisk_id"="$IRONIC_DEPLOY_RAMDISK_ID"
 
     # intentional sleep to make sure the tag has been set to port
     sleep 10
@@ -348,13 +389,22 @@
 
     sudo ovs-vsctl -- --if-exists del-port ovs-tap1 -- add-port br-int ovs-tap1 tag=$TAG_ID
     sudo ovs-vsctl -- --if-exists del-port brbm-tap1 -- add-port $IRONIC_VM_NETWORK_BRIDGE brbm-tap1
+
+    # Remove the port needed only for workaround. For additional info read the
+    # comment at the beginning of this function
+    neutron port-delete $PORT_ID
+}
+
+function configure_iptables {
+    # enable tftp natting for allowing connections to HOST_IP's tftp server
+    sudo modprobe nf_conntrack_tftp
+    sudo modprobe nf_nat_tftp
+    # nodes boot from TFTP and callback to the API server listening on $HOST_IP
+    sudo iptables -I INPUT -d $HOST_IP -p udp --dport 69 -j ACCEPT || true
+    sudo iptables -I INPUT -d $HOST_IP -p tcp --dport 6385 -j ACCEPT || true
 }
 
 function configure_tftpd {
-    # enable tftp natting for allowing connections to SERVICE_HOST's tftp server
-    sudo modprobe nf_conntrack_tftp
-    sudo modprobe nf_nat_tftp
-
     if is_ubuntu; then
         PXEBIN=/usr/lib/syslinux/pxelinux.0
     elif is_fedora; then
@@ -403,37 +453,61 @@
     fi
 }
 
-function configure_ironic_sshd {
-    # Ensure sshd server accepts connections from localhost only
-
-    SSH_CONFIG=/etc/ssh/sshd_config
-    HOST_PORT=$IRONIC_VM_SSH_ADDRESS:$IRONIC_VM_SSH_PORT
-    if ! sudo grep ListenAddress $SSH_CONFIG | grep $HOST_PORT; then
-        echo "ListenAddress $HOST_PORT" | sudo tee -a $SSH_CONFIG
-    fi
-
-    SSH_SERVICE_NAME=sshd
-    if is_ubuntu; then
-        SSH_SERVICE_NAME=ssh
-    fi
-
-    restart_service $SSH_SERVICE_NAME
-    # to ensure ssh service is up and running
-    sleep 3
-    ironic_ssh_check $IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME $IRONIC_VM_SSH_ADDRESS $IRONIC_VM_SSH_PORT $IRONIC_SSH_USERNAME 10
-
-}
-
 function configure_ironic_auxiliary {
     configure_ironic_dirs
     configure_ironic_ssh_keypair
-    configure_ironic_sshd
+    ironic_ssh_check $IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME $IRONIC_VM_SSH_ADDRESS $IRONIC_VM_SSH_PORT $IRONIC_SSH_USERNAME 10
+}
+
+# build deploy kernel+ramdisk, then upload them to glance
+# this function sets IRONIC_DEPLOY_KERNEL_ID and IRONIC_DEPLOY_RAMDISK_ID
+function upload_baremetal_ironic_deploy {
+    token=$1
+
+    if [ -z "$IRONIC_DEPLOY_KERNEL" -o -z "$IRONIC_DEPLOY_RAMDISK" ]; then
+        IRONIC_DEPLOY_KERNEL_PATH=$TOP_DIR/files/ir-deploy.kernel
+        IRONIC_DEPLOY_RAMDISK_PATH=$TOP_DIR/files/ir-deploy.initramfs
+    else
+        IRONIC_DEPLOY_KERNEL_PATH=$IRONIC_DEPLOY_KERNEL
+        IRONIC_DEPLOY_RAMDISK_PATH=$IRONIC_DEPLOY_RAMDISK
+    fi
+
+    if [ ! -e "$IRONIC_DEPLOY_RAMDISK_PATH" -o ! -e "$IRONIC_DEPLOY_KERNEL_PATH" ]; then
+        # files don't exist, need to build them
+        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
+            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"
+        fi
+    fi
+
+    # load them into glance
+    IRONIC_DEPLOY_KERNEL_ID=$(glance \
+        --os-auth-token $token \
+        --os-image-url http://$GLANCE_HOSTPORT \
+        image-create \
+        --name $(basename $IRONIC_DEPLOY_KERNEL_PATH) \
+        --is-public True --disk-format=aki \
+        < $IRONIC_DEPLOY_KERNEL_PATH  | grep ' id ' | get_field 2)
+    IRONIC_DEPLOY_RAMDISK_ID=$(glance \
+        --os-auth-token $token \
+        --os-image-url http://$GLANCE_HOSTPORT \
+        image-create \
+        --name $(basename $IRONIC_DEPLOY_RAMDISK_PATH) \
+        --is-public True --disk-format=ari \
+        < $IRONIC_DEPLOY_RAMDISK_PATH  | grep ' id ' | get_field 2)
 }
 
 function prepare_baremetal_basic_ops {
 
     # install diskimage-builder
-    git_clone $BM_IMAGE_BUILD_REPO $BM_IMAGE_BUILD_DIR $BM_IMAGE_BUILD_BRANCH
+    git_clone $DIB_REPO $DIB_DIR $DIB_BRANCH
 
     # make sure all needed service were enabled
     for srv in nova glance key neutron; do
@@ -442,30 +516,23 @@
         fi
     done
 
-    SCREEN_NAME=${SCREEN_NAME:-stack}
-    SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
-
-    # stop all nova services
-    stop_nova || true
-
-    # remove any nova services failure status
-    find $SERVICE_DIR/$SCREEN_NAME -name 'n-*.failure' -exec rm -f '{}' \;
-
-    # start them again
-    start_nova_api
-    start_nova
-
     TOKEN=$(keystone token-get | grep ' id ' | get_field 2)
     die_if_not_set $LINENO TOKEN "Keystone fail to get token"
 
     echo_summary "Creating and uploading baremetal images for ironic"
 
     # build and upload separate deploy kernel & ramdisk
-    upload_baremetal_deploy $TOKEN
+    upload_baremetal_ironic_deploy $TOKEN
 
     create_bridge_and_vms
     enroll_vms
     configure_tftpd
+    configure_iptables
+
+    # restart nova-compute to ensure its resource tracking is up to
+    # date with newly enrolled nodes
+    stop_nova_compute || true
+    start_nova_compute
 }
 
 function cleanup_baremetal_basic_ops {
@@ -480,6 +547,10 @@
     sudo su $STACK_USER -c "$IRONIC_SCRIPTS_DIR/cleanup-nodes $IRONIC_VM_COUNT $IRONIC_VM_NETWORK_BRIDGE"
     sudo rm -rf /etc/xinetd.d/tftp /etc/init/tftpd-hpa.override
     restart_service xinetd
+    sudo iptables -D INPUT -d $HOST_IP -p udp --dport 69 -j ACCEPT || true
+    sudo iptables -D INPUT -d $HOST_IP -p tcp --dport 6385 -j ACCEPT || true
+    sudo rmmod nf_conntrack_tftp || true
+    sudo rmmod nf_nat_tftp || true
 }
 
 # Restore xtrace + pipefail
diff --git a/lib/keystone b/lib/keystone
index b31cc57..f8e92f4 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -253,11 +253,17 @@
     fi
 
     # Format logging
-    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
+    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ] &&  ! is_apache_enabled_service key ; then
         setup_colorized_logging $KEYSTONE_CONF DEFAULT
     fi
 
     if is_apache_enabled_service key; then
+        iniset $KEYSTONE_CONF DEFAULT debug "True"
+        # Eliminate the %(asctime)s.%(msecs)03d from the log format strings
+        iniset $KEYSTONE_CONF DEFAULT logging_context_format_string "%(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s"
+        iniset $KEYSTONE_CONF DEFAULT logging_default_format_string "%(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s"
+        iniset $KEYSTONE_CONF DEFAULT logging_debug_format_suffix "%(funcName)s %(pathname)s:%(lineno)d"
+        iniset $KEYSTONE_CONF DEFAULT logging_exception_prefix "%(process)d TRACE %(name)s %(instance)s"
         _config_keystone_apache_wsgi
     fi
 }
@@ -450,6 +456,8 @@
 function stop_keystone {
     # Kill the Keystone screen window
     screen_stop key
+    # Cleanup the WSGI files and VHOST
+    _cleanup_keystone_apache_wsgi
 }
 
 
diff --git a/lib/marconi b/lib/marconi
index fd1c351..473c8cd 100644
--- a/lib/marconi
+++ b/lib/marconi
@@ -42,7 +42,7 @@
 MARCONI_BIN_DIR=$(get_python_exec_prefix)
 
 # Set up database backend
-MARCONI_BACKEND=${MARCONI_BACKEND:-mongodb}
+MARCONI_BACKEND=${MARCONI_BACKEND:-sqlite}
 
 
 # Set Marconi repository
@@ -109,8 +109,8 @@
     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`
-    else
-        iniset $MARCONI_CONF drivers storage mongodb
+    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
@@ -154,7 +154,7 @@
 
 # start_marconi() - Start running processes, including screen
 function start_marconi {
-    screen_it marconi-server "marconi-server --config-file $MARCONI_CONF"
+    screen_it marconi-server "marconi-server --config-file $MARCONI_CONF --daemon"
     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"
diff --git a/lib/neutron b/lib/neutron
index 84e8277..15cfa8e 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -127,6 +127,10 @@
 # See _configure_neutron_common() for details about setting it up
 declare -a Q_PLUGIN_EXTRA_CONF_FILES
 
+# List of (optional) config files for VPN device drivers to use with
+# the neutron-q-vpn agent
+declare -a Q_VPN_EXTRA_CONF_FILES
+
 
 Q_RR_CONF_FILE=$NEUTRON_CONF_DIR/rootwrap.conf
 if [[ "$Q_USE_ROOTWRAP" == "False" ]]; then
@@ -274,7 +278,7 @@
     if is_service_enabled q-fwaas; then
         _configure_neutron_fwaas
     fi
-    if is_service_enabled q-svc; then
+    if is_service_enabled q-agt q-svc; then
         _configure_neutron_service
     fi
     if is_service_enabled q-agt; then
@@ -312,7 +316,7 @@
     # set NOVA_VIF_DRIVER and optionally set options in nova_conf
     neutron_plugin_create_nova_conf
 
-    iniset $NOVA_CONF DEFAULT libvirt_vif_driver "$NOVA_VIF_DRIVER"
+    iniset $NOVA_CONF libvirt vif_driver "$NOVA_VIF_DRIVER"
     iniset $NOVA_CONF DEFAULT linuxnet_interface_driver "$LINUXNET_VIF_DRIVER"
     if is_service_enabled q-meta; then
         iniset $NOVA_CONF DEFAULT service_neutron_metadata_proxy "True"
@@ -493,9 +497,10 @@
 
     if is_service_enabled q-fwaas; then
         L3_CONF_FILES="$L3_CONF_FILES --config-file $Q_FWAAS_CONF_FILE"
+        VPN_CONF_FILES="$VPN_CONF_FILES --config-file $Q_FWAAS_CONF_FILE"
     fi
     if is_service_enabled q-vpn; then
-        screen_it q-vpn "cd $NEUTRON_DIR && $AGENT_VPN_BINARY $L3_CONF_FILES"
+        screen_it q-vpn "cd $NEUTRON_DIR && $AGENT_VPN_BINARY $VPN_CONF_FILES"
     else
         screen_it q-l3 "cd $NEUTRON_DIR && python $AGENT_L3_BINARY $L3_CONF_FILES"
     fi
@@ -658,6 +663,7 @@
 }
 
 function _configure_neutron_l3_agent {
+    local cfg_file
     Q_L3_ENABLED=True
     # for l3-agent, only use per tenant router if we have namespaces
     Q_L3_ROUTER_PER_TENANT=$Q_USE_NAMESPACE
@@ -669,6 +675,15 @@
         Q_FWAAS_CONF_FILE=$NEUTRON_CONF_DIR/fwaas_driver.ini
     fi
 
+    if is_service_enabled q-vpn; then
+        Q_VPN_CONF_FILE=$NEUTRON_CONF_DIR/vpn_agent.ini
+        cp $NEUTRON_DIR/etc/vpn_agent.ini $Q_VPN_CONF_FILE
+        VPN_CONF_FILES="--config-file $NEUTRON_CONF --config-file=$Q_L3_CONF_FILE --config-file=$Q_VPN_CONF_FILE"
+        for cfg_file in ${Q_VPN_EXTRA_CONF_FILES[@]}; do
+            VPN_CONF_FILES+=" --config-file $cfg_file"
+        done
+    fi
+
     cp $NEUTRON_DIR/etc/l3_agent.ini $Q_L3_CONF_FILE
 
     iniset $Q_L3_CONF_FILE DEFAULT verbose True
@@ -762,10 +777,10 @@
     done
 
     # Configuration for neutron notifations to nova.
-    iniset $NEUTRON_CONF DEFAULT notify_nova_port_status_change $Q_NOTIFY_NOVA_PORT_STATUS_CHANGE
+    iniset $NEUTRON_CONF DEFAULT notify_nova_on_port_status_change $Q_NOTIFY_NOVA_PORT_STATUS_CHANGE
     iniset $NEUTRON_CONF DEFAULT notify_nova_on_port_data_changes $Q_NOTIFY_NOVA_ON_PORT_DATA_CHANGES
     iniset $NEUTRON_CONF DEFAULT nova_url "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2"
-    iniset $NEUTRON_CONF DEFAULT nova_admin_username nova $NOVA_USER
+    iniset $NEUTRON_CONF DEFAULT nova_admin_username nova
     iniset $NEUTRON_CONF DEFAULT nova_admin_password $SERVICE_PASSWORD
     ADMIN_TENANT_ID=$(openstack project list | awk "/ service / { print \$2 }")
     iniset $NEUTRON_CONF DEFAULT nova_admin_tenant_id $ADMIN_TENANT_ID
diff --git a/lib/neutron_plugins/bigswitch_floodlight b/lib/neutron_plugins/bigswitch_floodlight
index 4cb0da8..efdd9ef 100644
--- a/lib/neutron_plugins/bigswitch_floodlight
+++ b/lib/neutron_plugins/bigswitch_floodlight
@@ -2,7 +2,7 @@
 # ------------------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+BS_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/ovs_base
@@ -38,7 +38,12 @@
 }
 
 function neutron_plugin_configure_plugin_agent {
-    :
+    # Set up integration bridge
+    _neutron_ovs_base_setup_bridge $OVS_BRIDGE
+    iniset /$Q_PLUGIN_CONF_FILE restproxyagent integration_bridge $OVS_BRIDGE
+    AGENT_BINARY="$NEUTRON_DIR/neutron/plugins/bigswitch/agent/restproxy_agent.py"
+
+    _neutron_ovs_base_configure_firewall_driver
 }
 
 function neutron_plugin_configure_service {
@@ -61,7 +66,7 @@
 
 function has_neutron_plugin_security_group {
     # 1 means False here
-    return 1
+    return 0
 }
 
 function neutron_plugin_check_adv_test_requirements {
@@ -69,4 +74,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$BS_XTRACE
diff --git a/lib/neutron_plugins/brocade b/lib/neutron_plugins/brocade
index 4443fa7..e4cc754 100644
--- a/lib/neutron_plugins/brocade
+++ b/lib/neutron_plugins/brocade
@@ -24,6 +24,30 @@
     Q_PLUGIN_CLASS="neutron.plugins.brocade.NeutronPlugin.BrocadePluginV2"
 }
 
+function neutron_plugin_configure_service {
+
+    if [[ "$BROCADE_SWITCH_OS_VERSION" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE switch osversion $BROCADE_SWITCH_OS_VERSION
+    fi
+
+    if [[ "$BROCADE_SWITCH_OS_TYPE" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE switch ostype $BROCADE_SWITCH_OS_TYPE
+    fi
+
+    if [[ "$BROCADE_SWITCH_PASSWORD" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE switch password $BROCADE_SWITCH_PASSWORD
+    fi
+
+    if [[ "$BROCADE_SWITCH_USERNAME" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE switch username $BROCADE_SWITCH_USERNAME
+    fi
+
+    if [[ "$BROCADE_SWITCH_IPADDR" != "" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE switch address $BROCADE_SWITCH_IPADDR
+    fi
+
+}
+
 function neutron_plugin_configure_debug_command {
     iniset $NEUTRON_TEST_CONFIG_FILE DEFAULT external_network_bridge
 }
diff --git a/lib/neutron_plugins/cisco b/lib/neutron_plugins/cisco
index a1b089e..dccf400 100644
--- a/lib/neutron_plugins/cisco
+++ b/lib/neutron_plugins/cisco
@@ -2,7 +2,7 @@
 # ---------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+CISCO_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 # Scecify the VSM parameters
@@ -183,6 +183,15 @@
         ovs_neutron_plugin_configure_common
         Q_PLUGIN_EXTRA_CONF_PATH=etc/neutron/plugins/cisco
         Q_PLUGIN_EXTRA_CONF_FILES=(cisco_plugins.ini)
+        # Copy extra config files to /etc so that they can be modified
+        # later according to Cisco-specific localrc settings.
+        mkdir -p /$Q_PLUGIN_EXTRA_CONF_PATH
+        local f
+        local extra_conf_file
+        for (( f=0; $f < ${#Q_PLUGIN_EXTRA_CONF_FILES[@]}; f+=1 )); do
+            extra_conf_file=$Q_PLUGIN_EXTRA_CONF_PATH/${Q_PLUGIN_EXTRA_CONF_FILES[$f]}
+            cp $NEUTRON_DIR/$extra_conf_file /$extra_conf_file
+        done
     else
         Q_PLUGIN_CONF_PATH=etc/neutron/plugins/cisco
         Q_PLUGIN_CONF_FILENAME=cisco_plugins.ini
@@ -324,4 +333,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$CISCO_XTRACE
diff --git a/lib/neutron_plugins/embrane b/lib/neutron_plugins/embrane
index 62f9737..cce108a 100644
--- a/lib/neutron_plugins/embrane
+++ b/lib/neutron_plugins/embrane
@@ -2,7 +2,7 @@
 # ---------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+EMBR_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/openvswitch
@@ -37,4 +37,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$EMBR_XTRACE
diff --git a/lib/neutron_plugins/ibm b/lib/neutron_plugins/ibm
index 22c8578..3aef9d0 100644
--- a/lib/neutron_plugins/ibm
+++ b/lib/neutron_plugins/ibm
@@ -2,7 +2,7 @@
 # ---------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+IBM_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/ovs_base
@@ -130,4 +130,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$IBM_XTRACE
diff --git a/lib/neutron_plugins/linuxbridge b/lib/neutron_plugins/linuxbridge
index 362fd5b..113a7df 100644
--- a/lib/neutron_plugins/linuxbridge
+++ b/lib/neutron_plugins/linuxbridge
@@ -2,7 +2,7 @@
 # ---------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+LBRIDGE_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/linuxbridge_agent
@@ -15,7 +15,7 @@
 }
 
 function neutron_plugin_configure_service {
-    if [[ "$ENABLE_TENANT_VLANS" = "True" ]]; then
+    if [[ "$ENABLE_TENANT_VLANS" == "True" ]]; then
         iniset /$Q_PLUGIN_CONF_FILE vlans tenant_network_type vlan
     else
         echo "WARNING - The linuxbridge plugin is using local tenant networks, with no connectivity between hosts."
@@ -23,7 +23,7 @@
 
     # Override ``LB_VLAN_RANGES`` and ``LB_INTERFACE_MAPPINGS`` in ``localrc``
     # for more complex physical network configurations.
-    if [[ "$LB_VLAN_RANGES" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
+    if [[ "$LB_VLAN_RANGES" == "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
         LB_VLAN_RANGES=$PHYSICAL_NETWORK
         if [[ "$TENANT_VLAN_RANGE" != "" ]]; then
             LB_VLAN_RANGES=$LB_VLAN_RANGES:$TENANT_VLAN_RANGE
@@ -53,4 +53,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$LBRIDGE_XTRACE
diff --git a/lib/neutron_plugins/linuxbridge_agent b/lib/neutron_plugins/linuxbridge_agent
index 74799e4..82b5fc9 100644
--- a/lib/neutron_plugins/linuxbridge_agent
+++ b/lib/neutron_plugins/linuxbridge_agent
@@ -35,7 +35,7 @@
     # Setup physical network interface mappings.  Override
     # ``LB_VLAN_RANGES`` and ``LB_INTERFACE_MAPPINGS`` in ``localrc`` for more
     # complex physical network configurations.
-    if [[ "$LB_INTERFACE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$LB_PHYSICAL_INTERFACE" != "" ]]; then
+    if [[ "$LB_INTERFACE_MAPPINGS" == "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$LB_PHYSICAL_INTERFACE" != "" ]]; then
         LB_INTERFACE_MAPPINGS=$PHYSICAL_NETWORK:$LB_PHYSICAL_INTERFACE
     fi
     if [[ "$LB_INTERFACE_MAPPINGS" != "" ]]; then
diff --git a/lib/neutron_plugins/midonet b/lib/neutron_plugins/midonet
index 742e3b2..c5373d6 100644
--- a/lib/neutron_plugins/midonet
+++ b/lib/neutron_plugins/midonet
@@ -6,7 +6,7 @@
 MIDONET_API_URL=${MIDONET_API_URL:-http://localhost:$MIDONET_API_PORT/midonet-api}
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+MN_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 function is_neutron_ovs_base_plugin {
@@ -84,4 +84,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$MN_XTRACE
diff --git a/lib/neutron_plugins/ml2 b/lib/neutron_plugins/ml2
index e985dcb..9966373 100644
--- a/lib/neutron_plugins/ml2
+++ b/lib/neutron_plugins/ml2
@@ -2,7 +2,7 @@
 # ------------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+ML2_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 # Enable this to simply and quickly enable tunneling with ML2.
@@ -11,7 +11,7 @@
 # This has to be set here since the agent will set this in the config file
 if [[ "$Q_ML2_TENANT_NETWORK_TYPE" != "" ]]; then
     Q_AGENT_EXTRA_AGENT_OPTS+=(tunnel_types=$Q_ML2_TENANT_NETWORK_TYPE)
-elif [[ "$ENABLE_TENANT_TUNNELS" = "True" ]]; then
+elif [[ "$ENABLE_TENANT_TUNNELS" == "True" ]]; then
     Q_AGENT_EXTRA_AGENT_OPTS+=(tunnel_types=gre)
 fi
 
@@ -60,12 +60,12 @@
 function neutron_plugin_configure_service {
     if [[ "$Q_ML2_TENANT_NETWORK_TYPE" != "" ]]; then
         Q_SRV_EXTRA_OPTS+=(tenant_network_types=$Q_ML2_TENANT_NETWORK_TYPE)
-    elif [[ "$ENABLE_TENANT_TUNNELS" = "True" ]]; then
+    elif [[ "$ENABLE_TENANT_TUNNELS" == "True" ]]; then
         # This assumes you want a simple configuration, and will overwrite
         # Q_SRV_EXTRA_OPTS if set in addition to ENABLE_TENANT_TUNNELS.
         Q_SRV_EXTRA_OPTS+=(tenant_network_types=gre)
         Q_ML2_PLUGIN_GRE_TYPE_OPTIONS=(tunnel_id_ranges=$TENANT_TUNNEL_RANGES)
-    elif [[ "$ENABLE_TENANT_VLANS" = "True" ]]; then
+    elif [[ "$ENABLE_TENANT_VLANS" == "True" ]]; then
         Q_SRV_EXTRA_OPTS+=(tenant_network_types=vlan)
     else
         echo "WARNING - The ml2 plugin is using local tenant networks, with no connectivity between hosts."
@@ -74,7 +74,7 @@
     # Allow for overrding VLAN configuration (for example, to configure provider
     # VLANs) by first checking if Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS is set.
     if [ "$Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS" == "" ]; then
-        if [[ "$ML2_VLAN_RANGES" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
+        if [[ "$ML2_VLAN_RANGES" == "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
             ML2_VLAN_RANGES=$PHYSICAL_NETWORK
             if [[ "$TENANT_VLAN_RANGE" != "" ]]; then
                 ML2_VLAN_RANGES=$ML2_VLAN_RANGES:$TENANT_VLAN_RANGE
@@ -119,4 +119,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$ML2_XTRACE
diff --git a/lib/neutron_plugins/nec b/lib/neutron_plugins/nec
index 6d4bfca..d76f7d4 100644
--- a/lib/neutron_plugins/nec
+++ b/lib/neutron_plugins/nec
@@ -2,7 +2,7 @@
 # ---------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+NEC_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 # Configuration parameters
@@ -127,4 +127,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$NEC_XTRACE
diff --git a/lib/neutron_plugins/nuage b/lib/neutron_plugins/nuage
index 3649f39..86f09d2 100644
--- a/lib/neutron_plugins/nuage
+++ b/lib/neutron_plugins/nuage
@@ -2,7 +2,7 @@
 # ----------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+NU_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 function neutron_plugin_create_nova_conf {
@@ -66,4 +66,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$NU_XTRACE
diff --git a/lib/neutron_plugins/ofagent_agent b/lib/neutron_plugins/ofagent_agent
index 724df41..b8321f3 100644
--- a/lib/neutron_plugins/ofagent_agent
+++ b/lib/neutron_plugins/ofagent_agent
@@ -2,7 +2,7 @@
 # ----------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+OFA_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/ovs_base
@@ -46,7 +46,7 @@
     fi
 
     # Enable tunnel networks if selected
-    if [[ "$OVS_ENABLE_TUNNELING" = "True" ]]; then
+    if [[ "$OVS_ENABLE_TUNNELING" == "True" ]]; then
         # Verify tunnels are supported
         # REVISIT - also check kernel module support for GRE and patch ports
         OVS_VERSION=`ovs-vsctl --version | head -n 1 | grep -E -o "[0-9]+\.[0-9]+"`
@@ -60,7 +60,7 @@
     # Setup physical network bridge mappings.  Override
     # ``OVS_VLAN_RANGES`` and ``OVS_BRIDGE_MAPPINGS`` in ``localrc`` for more
     # complex physical network configurations.
-    if [[ "$OVS_BRIDGE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$OVS_PHYSICAL_BRIDGE" != "" ]]; then
+    if [[ "$OVS_BRIDGE_MAPPINGS" == "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$OVS_PHYSICAL_BRIDGE" != "" ]]; then
         OVS_BRIDGE_MAPPINGS=$PHYSICAL_NETWORK:$OVS_PHYSICAL_BRIDGE
 
         # Configure bridge manually with physical interface as port for multi-node
@@ -91,4 +91,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$OFA_XTRACE
diff --git a/lib/neutron_plugins/oneconvergence b/lib/neutron_plugins/oneconvergence
index 0aebff6..06f1eee 100644
--- a/lib/neutron_plugins/oneconvergence
+++ b/lib/neutron_plugins/oneconvergence
@@ -1,7 +1,7 @@
 # Neutron One Convergence plugin
 # ---------------------------
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+OC_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/ovs_base
@@ -73,4 +73,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$OC_XTRACE
diff --git a/lib/neutron_plugins/openvswitch b/lib/neutron_plugins/openvswitch
index bdbc5a9..fc81092 100644
--- a/lib/neutron_plugins/openvswitch
+++ b/lib/neutron_plugins/openvswitch
@@ -2,7 +2,7 @@
 # ---------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+OVS_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/openvswitch_agent
@@ -15,10 +15,10 @@
 }
 
 function neutron_plugin_configure_service {
-    if [[ "$ENABLE_TENANT_TUNNELS" = "True" ]]; then
+    if [[ "$ENABLE_TENANT_TUNNELS" == "True" ]]; then
         iniset /$Q_PLUGIN_CONF_FILE ovs tenant_network_type gre
         iniset /$Q_PLUGIN_CONF_FILE ovs tunnel_id_ranges $TENANT_TUNNEL_RANGES
-    elif [[ "$ENABLE_TENANT_VLANS" = "True" ]]; then
+    elif [[ "$ENABLE_TENANT_VLANS" == "True" ]]; then
         iniset /$Q_PLUGIN_CONF_FILE ovs tenant_network_type vlan
     else
         echo "WARNING - The openvswitch plugin is using local tenant networks, with no connectivity between hosts."
@@ -26,7 +26,7 @@
 
     # Override ``OVS_VLAN_RANGES`` and ``OVS_BRIDGE_MAPPINGS`` in ``localrc``
     # for more complex physical network configurations.
-    if [[ "$OVS_VLAN_RANGES" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
+    if [[ "$OVS_VLAN_RANGES" == "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]]; then
         OVS_VLAN_RANGES=$PHYSICAL_NETWORK
         if [[ "$TENANT_VLAN_RANGE" != "" ]]; then
             OVS_VLAN_RANGES=$OVS_VLAN_RANGES:$TENANT_VLAN_RANGE
@@ -37,7 +37,7 @@
     fi
 
     # Enable tunnel networks if selected
-    if [[ $OVS_ENABLE_TUNNELING = "True" ]]; then
+    if [[ $OVS_ENABLE_TUNNELING == "True" ]]; then
         iniset /$Q_PLUGIN_CONF_FILE ovs enable_tunneling True
     fi
 
@@ -57,4 +57,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$OVS_XTRACE
diff --git a/lib/neutron_plugins/openvswitch_agent b/lib/neutron_plugins/openvswitch_agent
index 3a2bdc3..fbc013f 100644
--- a/lib/neutron_plugins/openvswitch_agent
+++ b/lib/neutron_plugins/openvswitch_agent
@@ -2,16 +2,16 @@
 # -----------------------------
 
 # Save trace setting
-PLUGIN_XTRACE=$(set +o | grep xtrace)
+OVSA_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/ovs_base
 
 function neutron_plugin_create_nova_conf {
     _neutron_ovs_base_configure_nova_vif_driver
-    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
-        iniset $NOVA_CONF DEFAULT xenapi_vif_driver nova.virt.xenapi.vif.XenAPIOpenVswitchDriver
-        iniset $NOVA_CONF DEFAULT xenapi_ovs_integration_bridge $XEN_INTEGRATION_BRIDGE
+    if [ "$VIRT_DRIVER" == 'xenserver' ]; then
+        iniset $NOVA_CONF xenserver vif_driver nova.virt.xenapi.vif.XenAPIOpenVswitchDriver
+        iniset $NOVA_CONF xenserver ovs_integration_bridge $XEN_INTEGRATION_BRIDGE
         # Disable nova's firewall so that it does not conflict with neutron
         iniset $NOVA_CONF DEFAULT firewall_driver nova.virt.firewall.NoopFirewallDriver
     fi
@@ -40,7 +40,7 @@
     _neutron_ovs_base_configure_firewall_driver
 
     # Setup agent for tunneling
-    if [[ "$OVS_ENABLE_TUNNELING" = "True" ]]; then
+    if [[ "$OVS_ENABLE_TUNNELING" == "True" ]]; then
         # Verify tunnels are supported
         # REVISIT - also check kernel module support for GRE and patch ports
         OVS_VERSION=`ovs-vsctl --version | head -n 1 | grep -E -o "[0-9]+\.[0-9]+"`
@@ -54,7 +54,7 @@
     # Setup physical network bridge mappings.  Override
     # ``OVS_VLAN_RANGES`` and ``OVS_BRIDGE_MAPPINGS`` in ``localrc`` for more
     # complex physical network configurations.
-    if [[ "$OVS_BRIDGE_MAPPINGS" = "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$OVS_PHYSICAL_BRIDGE" != "" ]]; then
+    if [[ "$OVS_BRIDGE_MAPPINGS" == "" ]] && [[ "$PHYSICAL_NETWORK" != "" ]] && [[ "$OVS_PHYSICAL_BRIDGE" != "" ]]; then
         OVS_BRIDGE_MAPPINGS=$PHYSICAL_NETWORK:$OVS_PHYSICAL_BRIDGE
 
         # Configure bridge manually with physical interface as port for multi-node
@@ -65,7 +65,7 @@
     fi
     AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-openvswitch-agent"
 
-    if [ "$VIRT_DRIVER" = 'xenserver' ]; then
+    if [ "$VIRT_DRIVER" == 'xenserver' ]; then
         # Make a copy of our config for domU
         sudo cp /$Q_PLUGIN_CONF_FILE "/$Q_PLUGIN_CONF_FILE.domu"
 
@@ -128,4 +128,4 @@
 }
 
 # Restore xtrace
-$PLUGIN_XTRACE
+$OVSA_XTRACE
diff --git a/lib/neutron_plugins/ovs_base b/lib/neutron_plugins/ovs_base
index 0a2ba58..1e293a1 100644
--- a/lib/neutron_plugins/ovs_base
+++ b/lib/neutron_plugins/ovs_base
@@ -2,7 +2,7 @@
 # -------------------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+OVSB_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 OVS_BRIDGE=${OVS_BRIDGE:-br-int}
@@ -44,9 +44,8 @@
         # Ensure that the service is started
         restart_service openvswitch
     elif is_suse; then
-        install_package openvswitch
+        install_package openvswitch-switch
         restart_service openvswitch-switch
-        restart_service openvswitch-controller
     fi
 }
 
@@ -77,4 +76,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$OVSB_XTRACE
diff --git a/lib/neutron_plugins/plumgrid b/lib/neutron_plugins/plumgrid
index 19f94cb..178bca7 100644
--- a/lib/neutron_plugins/plumgrid
+++ b/lib/neutron_plugins/plumgrid
@@ -3,7 +3,7 @@
 # ------------------------------------
 
 # Save trace settings
-MY_XTRACE=$(set +o | grep xtrace)
+PG_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 function neutron_plugin_create_nova_conf {
@@ -24,14 +24,16 @@
     PLUMGRID_ADMIN=${PLUMGRID_ADMIN:-username}
     PLUMGRID_PASSWORD=${PLUMGRID_PASSWORD:-password}
     PLUMGRID_TIMEOUT=${PLUMGRID_TIMEOUT:-70}
+    PLUMGRID_DRIVER=${PLUMGRID_DRIVER:-neutron.plugins.plumgrid.drivers.fake_plumlib.Plumlib}
 }
 
 function neutron_plugin_configure_service {
-    iniset /$Q_PLUGIN_CONF_FILE PLUMgridDirector director_server $PLUMGRID_DIRECTOR_IP
-    iniset /$Q_PLUGIN_CONF_FILE PLUMgridDirector director_server_port $PLUMGRID_DIRECTOR_PORT
-    iniset /$Q_PLUGIN_CONF_FILE PLUMgridDirector username $PLUMGRID_ADMIN
-    iniset /$Q_PLUGIN_CONF_FILE PLUMgridDirector password $PLUMGRID_PASSWORD
-    iniset /$Q_PLUGIN_CONF_FILE PLUMgridDirector servertimeout $PLUMGRID_TIMEOUT
+    iniset /$Q_PLUGIN_CONF_FILE plumgriddirector director_server $PLUMGRID_DIRECTOR_IP
+    iniset /$Q_PLUGIN_CONF_FILE plumgriddirector director_server_port $PLUMGRID_DIRECTOR_PORT
+    iniset /$Q_PLUGIN_CONF_FILE plumgriddirector username $PLUMGRID_ADMIN
+    iniset /$Q_PLUGIN_CONF_FILE plumgriddirector password $PLUMGRID_PASSWORD
+    iniset /$Q_PLUGIN_CONF_FILE plumgriddirector servertimeout $PLUMGRID_TIMEOUT
+    iniset /$Q_PLUGIN_CONF_FILE plumgriddirector driver $PLUMGRID_DRIVER
 }
 
 function neutron_plugin_configure_debug_command {
@@ -52,4 +54,4 @@
     is_service_enabled q-agt && is_service_enabled q-dhcp && return 0
 }
 # Restore xtrace
-$MY_XTRACE
+$PG_XTRACE
diff --git a/lib/neutron_plugins/ryu b/lib/neutron_plugins/ryu
index 9ae36d3..ceb89fa 100644
--- a/lib/neutron_plugins/ryu
+++ b/lib/neutron_plugins/ryu
@@ -2,7 +2,7 @@
 # ------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+RYU_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/ovs_base
@@ -77,4 +77,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$RYU_XTRACE
diff --git a/lib/neutron_plugins/services/firewall b/lib/neutron_plugins/services/firewall
index ab6c324..b5253db 100644
--- a/lib/neutron_plugins/services/firewall
+++ b/lib/neutron_plugins/services/firewall
@@ -2,7 +2,7 @@
 # ---------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+FW_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 FWAAS_PLUGIN=neutron.services.firewall.fwaas_plugin.FirewallPlugin
@@ -24,4 +24,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$FW_XTRACE
diff --git a/lib/neutron_plugins/services/loadbalancer b/lib/neutron_plugins/services/loadbalancer
index 531f52f..78e7738 100644
--- a/lib/neutron_plugins/services/loadbalancer
+++ b/lib/neutron_plugins/services/loadbalancer
@@ -2,7 +2,7 @@
 # ---------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+LB_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -48,4 +48,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$LB_XTRACE
diff --git a/lib/neutron_plugins/services/metering b/lib/neutron_plugins/services/metering
index 0e5f75b..51123e2 100644
--- a/lib/neutron_plugins/services/metering
+++ b/lib/neutron_plugins/services/metering
@@ -2,7 +2,7 @@
 # ---------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+METER_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -27,4 +27,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$METER_XTRACE
diff --git a/lib/neutron_plugins/services/vpn b/lib/neutron_plugins/services/vpn
index e56d361..d920ba6 100644
--- a/lib/neutron_plugins/services/vpn
+++ b/lib/neutron_plugins/services/vpn
@@ -2,7 +2,7 @@
 # ---------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+VPN_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -30,4 +30,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$VPN_XTRACE
diff --git a/lib/neutron_plugins/vmware_nsx b/lib/neutron_plugins/vmware_nsx
index fe79354..f2f8735 100644
--- a/lib/neutron_plugins/vmware_nsx
+++ b/lib/neutron_plugins/vmware_nsx
@@ -2,7 +2,7 @@
 # -------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+NSX_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/ovs_base
@@ -146,4 +146,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$NSX_XTRACE
diff --git a/lib/neutron_thirdparty/bigswitch_floodlight b/lib/neutron_thirdparty/bigswitch_floodlight
index f03de56..033731e 100644
--- a/lib/neutron_thirdparty/bigswitch_floodlight
+++ b/lib/neutron_thirdparty/bigswitch_floodlight
@@ -2,7 +2,7 @@
 # ------------------------------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+BS3_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 BS_FL_CONTROLLERS_PORT=${BS_FL_CONTROLLERS_PORT:-localhost:80}
@@ -49,4 +49,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$BS3_XTRACE
diff --git a/lib/neutron_thirdparty/midonet b/lib/neutron_thirdparty/midonet
index ad417bb..099a66e 100644
--- a/lib/neutron_thirdparty/midonet
+++ b/lib/neutron_thirdparty/midonet
@@ -17,7 +17,7 @@
 MIDONET_CLIENT_DIR=${MIDONET_CLIENT_DIR:-$MIDONET_DIR/python-midonetclient}
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+MN3_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 function configure_midonet {
@@ -46,4 +46,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$MN3_XTRACE
diff --git a/lib/neutron_thirdparty/ryu b/lib/neutron_thirdparty/ryu
index b2c1b61..bbe227e 100644
--- a/lib/neutron_thirdparty/ryu
+++ b/lib/neutron_thirdparty/ryu
@@ -2,7 +2,7 @@
 # -----------------------
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+RYU3_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -75,4 +75,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$RYU3_XTRACE
diff --git a/lib/neutron_thirdparty/trema b/lib/neutron_thirdparty/trema
index d465ac7..f829aa8 100644
--- a/lib/neutron_thirdparty/trema
+++ b/lib/neutron_thirdparty/trema
@@ -13,7 +13,7 @@
 TREMA_APPS_BRANCH=${TREMA_APPS_BRANCH:-master}
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+TREMA3_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 TREMA_DIR=${TREMA_DIR:-$DEST/trema}
@@ -114,4 +114,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$TREMA3_XTRACE
diff --git a/lib/neutron_thirdparty/vmware_nsx b/lib/neutron_thirdparty/vmware_nsx
index 3fecc62..7a76570 100644
--- a/lib/neutron_thirdparty/vmware_nsx
+++ b/lib/neutron_thirdparty/vmware_nsx
@@ -11,7 +11,7 @@
 # * NSX_GATEWAY_NETWORK_CIDR         --> CIDR to configure br-ex, e.g. 172.24.4.211/24
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+NSX3_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
 # This is the interface that connects the Devstack instance
@@ -83,4 +83,4 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$NSX3_XTRACE
diff --git a/lib/nova b/lib/nova
index 8240813..c51d584 100644
--- a/lib/nova
+++ b/lib/nova
@@ -139,7 +139,7 @@
 # Test if any Nova Cell services are enabled
 # is_nova_enabled
 function is_n-cell_enabled {
-    [[ ,${ENABLED_SERVICES} =~ ,"n-cell-" ]] && return 0
+    [[ ,${ENABLED_SERVICES} =~ ,"n-cell" ]] && return 0
     return 1
 }
 
@@ -303,6 +303,10 @@
                 sudo chown -R $STACK_USER $NOVA_INSTANCES_PATH
             fi
         fi
+        if is_suse; then
+            # iscsid is not started by default
+            start_service iscsid
+        fi
     fi
 
     # Rebuild the config file from scratch
@@ -428,7 +432,6 @@
     iniset $NOVA_CONF DEFAULT default_floating_pool "$PUBLIC_NETWORK_NAME"
     iniset $NOVA_CONF DEFAULT s3_host "$SERVICE_HOST"
     iniset $NOVA_CONF DEFAULT s3_port "$S3_SERVICE_PORT"
-    iniset $NOVA_CONF DEFAULT osapi_compute_extension "nova.api.openstack.compute.contrib.standard_extensions"
     iniset $NOVA_CONF DEFAULT my_ip "$HOST_IP"
     iniset $NOVA_CONF DEFAULT osapi_compute_workers "4"
     iniset $NOVA_CONF DEFAULT ec2_workers "4"
@@ -438,8 +441,8 @@
     iniset $NOVA_CONF DEFAULT instance_name_template "${INSTANCE_NAME_PREFIX}%08x"
     iniset $NOVA_CONF osapi_v3 enabled "True"
 
-    if is_fedora; then
-        # nova defaults to /usr/local/bin, but fedora pip likes to
+    if is_fedora || is_suse; then
+        # nova defaults to /usr/local/bin, but fedora and suse pip like to
         # install things in /usr/bin
         iniset $NOVA_CONF DEFAULT bindir "/usr/bin"
     fi
@@ -468,9 +471,6 @@
 
     iniset $NOVA_CONF keystone_authtoken signing_dir $NOVA_AUTH_CACHE_DIR
 
-    if is_service_enabled cinder; then
-        iniset $NOVA_CONF DEFAULT volume_api_class "nova.volume.cinder.API"
-    fi
     if [ -n "$NOVA_STATE_PATH" ]; then
         iniset $NOVA_CONF DEFAULT state_path "$NOVA_STATE_PATH"
         iniset $NOVA_CONF DEFAULT lock_path "$NOVA_STATE_PATH"
diff --git a/lib/nova_plugins/functions-libvirt b/lib/nova_plugins/functions-libvirt
index adffe01..f435456 100644
--- a/lib/nova_plugins/functions-libvirt
+++ b/lib/nova_plugins/functions-libvirt
@@ -18,7 +18,7 @@
 # Installs required distro-specific libvirt packages.
 function install_libvirt {
     if is_ubuntu; then
-        install_package kvm
+        install_package qemu-kvm
         install_package libvirt-bin
         install_package python-libvirt
         install_package python-guestfs
@@ -28,6 +28,23 @@
         install_package libvirt-python
         install_package python-libguestfs
     fi
+
+    # workaround for
+    # https://bugzilla.redhat.com/show_bug.cgi?id=1098376; if we see
+    # the empty Xen proc file then remove the xen/libxl plugin
+    # shared-libraries (yum remove would uninstall libvirt due to
+    # dependencies, so let's avoid that...)
+    if is_fedora && [ -f /proc/xen/capabilities ] && \
+        [ $(stat -c '%s' /proc/xen/capabilities) -eq 0 ]; then
+        sudo rm -f /usr/lib64/libvirt/connection-driver/libvirt_driver_libxl.so
+        sudo rm -f /usr/lib64/libvirt/connection-driver/libvirt_driver_xen.so
+
+        # another bug requires these to be restarted to avoid
+        # potential hang of libvirtd
+        # https://bugzilla.redhat.com/show_bug.cgi?id=1098866
+        sudo service dbus restart
+        sudo service firewalld restart
+    fi
 }
 
 # Configures the installed libvirt system so that is accessible by
diff --git a/lib/nova_plugins/hypervisor-baremetal b/lib/nova_plugins/hypervisor-baremetal
index 2da1097..1d4d414 100644
--- a/lib/nova_plugins/hypervisor-baremetal
+++ b/lib/nova_plugins/hypervisor-baremetal
@@ -49,7 +49,7 @@
     iniset $NOVA_CONF DEFAULT scheduler_host_manager nova.scheduler.baremetal_host_manager.BaremetalHostManager
     iniset $NOVA_CONF DEFAULT ram_allocation_ratio 1.0
     iniset $NOVA_CONF DEFAULT reserved_host_memory_mb 0
-    iniset $NOVA_CONF baremetal instance_type_extra_specs cpu_arch:$BM_CPU_ARCH
+    iniset $NOVA_CONF baremetal flavor_extra_specs cpu_arch:$BM_CPU_ARCH
     iniset $NOVA_CONF baremetal driver $BM_DRIVER
     iniset $NOVA_CONF baremetal power_manager $BM_POWER_MANAGER
     iniset $NOVA_CONF baremetal tftp_root /tftpboot
diff --git a/lib/nova_plugins/hypervisor-ironic b/lib/nova_plugins/hypervisor-ironic
index 5af7c0b..e72f7c1 100644
--- a/lib/nova_plugins/hypervisor-ironic
+++ b/lib/nova_plugins/hypervisor-ironic
@@ -18,6 +18,7 @@
 MY_XTRACE=$(set +o | grep xtrace)
 set +o xtrace
 
+source $TOP_DIR/lib/nova_plugins/functions-libvirt
 
 # Defaults
 # --------
@@ -33,8 +34,12 @@
 
 # configure_nova_hypervisor - Set config files, create data dirs, etc
 function configure_nova_hypervisor {
-    iniset $NOVA_CONF ironic sql_connection `database_connection_url nova_bm`
+    configure_libvirt
     LIBVIRT_FIREWALL_DRIVER=${LIBVIRT_FIREWALL_DRIVER:-"nova.virt.firewall.NoopFirewallDriver"}
+
+    # NOTE(adam_g): The ironic compute driver currently lives in the ironic
+    # tree.  We purposely configure Nova to load it from there until it moves
+    # back into Nova proper.
     iniset $NOVA_CONF DEFAULT compute_driver ironic.nova.virt.ironic.IronicDriver
     iniset $NOVA_CONF DEFAULT firewall_driver $LIBVIRT_FIREWALL_DRIVER
     iniset $NOVA_CONF DEFAULT scheduler_host_manager ironic.nova.scheduler.ironic_host_manager.IronicHostManager
@@ -45,13 +50,13 @@
     iniset $NOVA_CONF ironic admin_password $ADMIN_PASSWORD
     iniset $NOVA_CONF ironic admin_url $KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT/v2.0
     iniset $NOVA_CONF ironic admin_tenant_name demo
-    iniset $NOVA_CONF ironic api_endpoint http://$SERVICE_HOST:6358/v1
+    iniset $NOVA_CONF ironic api_endpoint http://$SERVICE_HOST:6385/v1
+    iniset $NOVA_CONF ironic sql_connection `database_connection_url nova_bm`
 }
 
 # install_nova_hypervisor() - Install external components
 function install_nova_hypervisor {
-    # This function intentionally left blank
-    :
+    install_libvirt
 }
 
 # start_nova_hypervisor - Start any required external services
diff --git a/lib/nova_plugins/hypervisor-libvirt b/lib/nova_plugins/hypervisor-libvirt
index 053df3c..259bf15 100644
--- a/lib/nova_plugins/hypervisor-libvirt
+++ b/lib/nova_plugins/hypervisor-libvirt
@@ -39,9 +39,9 @@
 # configure_nova_hypervisor - Set config files, create data dirs, etc
 function configure_nova_hypervisor {
     configure_libvirt
-    iniset $NOVA_CONF DEFAULT libvirt_type "$LIBVIRT_TYPE"
-    iniset $NOVA_CONF DEFAULT libvirt_cpu_mode "none"
-    iniset $NOVA_CONF DEFAULT use_usb_tablet "False"
+    iniset $NOVA_CONF libvirt virt_type "$LIBVIRT_TYPE"
+    iniset $NOVA_CONF libvirt cpu_mode "none"
+    iniset $NOVA_CONF libvirt use_usb_tablet "False"
     iniset $NOVA_CONF DEFAULT default_ephemeral_format "ext4"
     iniset $NOVA_CONF DEFAULT compute_driver "libvirt.LibvirtDriver"
     LIBVIRT_FIREWALL_DRIVER=${LIBVIRT_FIREWALL_DRIVER:-"nova.virt.libvirt.firewall.IptablesFirewallDriver"}
diff --git a/lib/nova_plugins/hypervisor-vsphere b/lib/nova_plugins/hypervisor-vsphere
index b04aeda..9933a3c 100644
--- a/lib/nova_plugins/hypervisor-vsphere
+++ b/lib/nova_plugins/hypervisor-vsphere
@@ -39,7 +39,7 @@
     iniset $NOVA_CONF vmware host_ip "$VMWAREAPI_IP"
     iniset $NOVA_CONF vmware host_username "$VMWAREAPI_USER"
     iniset $NOVA_CONF vmware host_password "$VMWAREAPI_PASSWORD"
-    iniset $NOVA_CONF vmware cluster_name "$VMWAREAPI_CLUSTER"
+    iniset_multiline $NOVA_CONF vmware cluster_name "$VMWAREAPI_CLUSTER"
     if is_service_enabled neutron; then
         iniset $NOVA_CONF vmware integration_bridge $OVS_BRIDGE
     fi
diff --git a/lib/nova_plugins/hypervisor-xenserver b/lib/nova_plugins/hypervisor-xenserver
index 10bda2c..c37969b 100644
--- a/lib/nova_plugins/hypervisor-xenserver
+++ b/lib/nova_plugins/hypervisor-xenserver
@@ -63,9 +63,13 @@
     local ssh_dom0
     ssh_dom0="sudo -u $DOMZERO_USER ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@$dom0_ip"
 
+    # Find where the plugins should go in dom0
+    xen_functions=`cat $TOP_DIR/tools/xen/functions`
+    PLUGIN_DIR=`$ssh_dom0 "$xen_functions; set -eux; xapi_plugin_location"`
+
     # install nova plugins to dom0
     tar -czf - -C $NOVA_DIR/plugins/xenserver/xenapi/etc/xapi.d/plugins/ ./ |
-        $ssh_dom0 'tar -xzf - -C /etc/xapi.d/plugins/ && chmod a+x /etc/xapi.d/plugins/*'
+        $ssh_dom0 "tar -xzf - -C $PLUGIN_DIR && chmod a+x $PLUGIN_DIR/*"
 
     # install console logrotate script
     tar -czf - -C $NOVA_DIR/tools/xenserver/ rotate_xen_guest_logs.sh |
diff --git a/lib/opendaylight b/lib/opendaylight
index ca81c20..be3db6e 100644
--- a/lib/opendaylight
+++ b/lib/opendaylight
@@ -35,6 +35,15 @@
 # ODL_MGR_IP=
 ODL_MGR_IP=${ODL_MGR_IP:-$SERVICE_HOST}
 
+# The ODL endpoint URL
+ODL_ENDPOINT=${ODL_ENDPOINT:-http://${ODL_MGR_IP}:8080/controller/nb/v2/neutron}
+
+# The ODL username
+ODL_USERNAME=${ODL_USERNAME:-admin}
+
+# The ODL password
+ODL_PASSWORD=${ODL_PASSWORD:-admin}
+
 # <define global variables here that belong to this project>
 ODL_DIR=$DEST/opendaylight
 
@@ -80,6 +89,12 @@
     echo "ovsdb.of.version=1.3" >> $ODL_DIR/opendaylight/configuration/config.ini
 }
 
+function configure_ml2_odl {
+    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_odl url=$ODL_ENDPOINT
+    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_odl username=$ODL_USERNAME
+    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_odl password=$ODL_PASSWORD
+}
+
 # init_opendaylight() - Initialize databases, etc.
 function init_opendaylight {
     # clean up from previous (possibly aborted) runs
@@ -117,9 +132,8 @@
         # Ensure that the service is started
         restart_service openvswitch
     elif is_suse; then
-        install_package openvswitch
+        install_package openvswitch-switch
         restart_service openvswitch-switch
-        restart_service openvswitch-controller
     fi
 }
 
@@ -134,7 +148,7 @@
     # The flags to ODL have the following meaning:
     #   -of13: runs ODL using OpenFlow 1.3 protocol support.
     #   -virt ovsdb: Runs ODL in "virtualization" mode with OVSDB support
-    screen_it odl-server "cd $ODL_DIR/opendaylight && JAVE_HOME=$JHOME ./run.sh $ODL_ARGS -of13 -virt ovsdb"
+    screen_it odl-server "cd $ODL_DIR/opendaylight && JAVA_HOME=$JHOME ./run.sh $ODL_ARGS -of13 -virt ovsdb"
 
     # Sleep a bit to let OpenDaylight finish starting up
     sleep $ODL_BOOT_WAIT
diff --git a/lib/oslo b/lib/oslo
index 8ef179c..3cf7218 100644
--- a/lib/oslo
+++ b/lib/oslo
@@ -39,28 +39,28 @@
     cleanup_oslo
 
     git_clone $CLIFF_REPO $CLIFF_DIR $CLIFF_BRANCH
-    setup_develop $CLIFF_DIR
+    setup_install $CLIFF_DIR
 
     git_clone $OSLOCFG_REPO $OSLOCFG_DIR $OSLOCFG_BRANCH
-    setup_develop $OSLOCFG_DIR
+    setup_install $OSLOCFG_DIR
 
     git_clone $OSLOMSG_REPO $OSLOMSG_DIR $OSLOMSG_BRANCH
-    setup_develop $OSLOMSG_DIR
+    setup_install $OSLOMSG_DIR
 
     git_clone $OSLORWRAP_REPO $OSLORWRAP_DIR $OSLORWRAP_BRANCH
-    setup_develop $OSLORWRAP_DIR
+    setup_install $OSLORWRAP_DIR
 
     git_clone $OSLOVMWARE_REPO $OSLOVMWARE_DIR $OSLOVMWARE_BRANCH
-    setup_develop $OSLOVMWARE_DIR
+    setup_install $OSLOVMWARE_DIR
 
     git_clone $PYCADF_REPO $PYCADF_DIR $PYCADF_BRANCH
-    setup_develop $PYCADF_DIR
+    setup_install $PYCADF_DIR
 
     git_clone $STEVEDORE_REPO $STEVEDORE_DIR $STEVEDORE_BRANCH
-    setup_develop $STEVEDORE_DIR
+    setup_install $STEVEDORE_DIR
 
     git_clone $TASKFLOW_REPO $TASKFLOW_DIR $TASKFLOW_BRANCH
-    setup_develop $TASKFLOW_DIR
+    setup_install $TASKFLOW_DIR
 }
 
 # cleanup_oslo() - purge possibly old versions of oslo
diff --git a/lib/sahara b/lib/sahara
index 71bd5b0..d56cf1b 100644
--- a/lib/sahara
+++ b/lib/sahara
@@ -28,7 +28,6 @@
 SAHARA_DIR=$DEST/sahara
 SAHARA_CONF_DIR=${SAHARA_CONF_DIR:-/etc/sahara}
 SAHARA_CONF_FILE=${SAHARA_CONF_DIR}/sahara.conf
-SAHARA_DEBUG=${SAHARA_DEBUG:-True}
 
 SAHARA_SERVICE_HOST=${SAHARA_SERVICE_HOST:-$SERVICE_HOST}
 SAHARA_SERVICE_PORT=${SAHARA_SERVICE_PORT:-8386}
@@ -36,6 +35,8 @@
 
 SAHARA_AUTH_CACHE_DIR=${SAHARA_AUTH_CACHE_DIR:-/var/cache/sahara}
 
+SAHARA_ENABLED_PLUGINS=${SAHARA_ENABLED_PLUGINS:-vanilla,hdp,fake}
+
 # Support entry points installation of console scripts
 if [[ -d $SAHARA_DIR/bin ]]; then
     SAHARA_BIN_DIR=$SAHARA_DIR/bin
@@ -102,8 +103,7 @@
     sudo chown $STACK_USER $SAHARA_CONF_DIR
 
     # Copy over sahara configuration file and configure common parameters.
-    # TODO(slukjanov): rename when sahara internals will be updated
-    cp $SAHARA_DIR/etc/savanna/savanna.conf.sample $SAHARA_CONF_FILE
+    cp $SAHARA_DIR/etc/sahara/sahara.conf.sample $SAHARA_CONF_FILE
 
     # Create auth cache dir
     sudo mkdir -p $SAHARA_AUTH_CACHE_DIR
@@ -111,22 +111,28 @@
     rm -rf $SAHARA_AUTH_CACHE_DIR/*
 
     # Set obsolete keystone auth configs for backward compatibility
-    iniset $SAHARA_CONF_FILE DEFAULT os_auth_host $KEYSTONE_SERVICE_HOST
-    iniset $SAHARA_CONF_FILE DEFAULT os_auth_port $KEYSTONE_SERVICE_PORT
-    iniset $SAHARA_CONF_FILE DEFAULT os_auth_protocol $KEYSTONE_SERVICE_PROTOCOL
+    iniset $SAHARA_CONF_FILE DEFAULT os_auth_host $KEYSTONE_AUTH_HOST
+    iniset $SAHARA_CONF_FILE DEFAULT os_auth_port $KEYSTONE_AUTH_PORT
+    iniset $SAHARA_CONF_FILE DEFAULT os_auth_protocol $KEYSTONE_AUTH_PROTOCOL
     iniset $SAHARA_CONF_FILE DEFAULT os_admin_password $SERVICE_PASSWORD
     iniset $SAHARA_CONF_FILE DEFAULT os_admin_username sahara
     iniset $SAHARA_CONF_FILE DEFAULT os_admin_tenant_name $SERVICE_TENANT_NAME
 
     # Set actual keystone auth configs
     iniset $SAHARA_CONF_FILE keystone_authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/
+    iniset $SAHARA_CONF_FILE keystone_authtoken auth_host $KEYSTONE_AUTH_HOST
+    iniset $SAHARA_CONF_FILE keystone_authtoken auth_port $KEYSTONE_AUTH_PORT
+    iniset $SAHARA_CONF_FILE keystone_authtoken auth_protocol $KEYSTONE_AUTH_PROTOCOL
     iniset $SAHARA_CONF_FILE keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
     iniset $SAHARA_CONF_FILE keystone_authtoken admin_user sahara
     iniset $SAHARA_CONF_FILE keystone_authtoken admin_password $SERVICE_PASSWORD
     iniset $SAHARA_CONF_FILE keystone_authtoken signing_dir $SAHARA_AUTH_CACHE_DIR
     iniset $SAHARA_CONF_FILE keystone_authtoken cafile $KEYSTONE_SSL_CA
 
-    iniset $SAHARA_CONF_FILE DEFAULT debug $SAHARA_DEBUG
+    iniset $SAHARA_CONF_FILE DEFAULT verbose True
+    iniset $SAHARA_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
+
+    iniset $SAHARA_CONF_FILE DEFAULT plugins $SAHARA_ENABLED_PLUGINS
 
     iniset $SAHARA_CONF_FILE database connection `database_connection_url sahara`
 
@@ -143,6 +149,11 @@
 
     iniset $SAHARA_CONF_FILE DEFAULT use_syslog $SYSLOG
 
+    # Format logging
+    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
+        setup_colorized_logging $SAHARA_CONF_FILE DEFAULT
+    fi
+
     recreate_database sahara utf8
     $SAHARA_BIN_DIR/sahara-db-manage --config-file $SAHARA_CONF_FILE upgrade head
 }
@@ -155,7 +166,7 @@
 
 # start_sahara() - Start running processes, including screen
 function start_sahara {
-    screen_it sahara "cd $SAHARA_DIR && $SAHARA_BIN_DIR/sahara-api --config-file $SAHARA_CONF_FILE"
+    screen_it sahara "cd $SAHARA_DIR && $SAHARA_BIN_DIR/sahara-all --config-file $SAHARA_CONF_FILE"
 }
 
 # stop_sahara() - Stop running processes
diff --git a/lib/stackforge b/lib/stackforge
index dca08cc..e6528af 100644
--- a/lib/stackforge
+++ b/lib/stackforge
@@ -40,10 +40,10 @@
     cleanup_stackforge
 
     git_clone $WSME_REPO $WSME_DIR $WSME_BRANCH
-    setup_develop_no_requirements_update $WSME_DIR
+    setup_package $WSME_DIR
 
     git_clone $PECAN_REPO $PECAN_DIR $PECAN_BRANCH
-    setup_develop_no_requirements_update $PECAN_DIR
+    setup_package $PECAN_DIR
 }
 
 # cleanup_stackforge() - purge possibly old versions of stackforge libraries
diff --git a/lib/swift b/lib/swift
index b655440..1e24c2c 100644
--- a/lib/swift
+++ b/lib/swift
@@ -103,6 +103,10 @@
 # trace through the logs when looking for its use.
 SWIFT_LOG_TOKEN_LENGTH=${SWIFT_LOG_TOKEN_LENGTH:-12}
 
+# Set ``SWIFT_MAX_HEADER_SIZE`` to configure the maximun length of headers in
+# Swift API
+SWIFT_MAX_HEADER_SIZE=${SWIFT_MAX_HEADER_SIZE:-16384}
+
 # Set ``OBJECT_PORT_BASE``, ``CONTAINER_PORT_BASE``, ``ACCOUNT_PORT_BASE``
 # Port bases used in port number calclution for the service "nodes"
 # The specified port number will be used, the additinal ports calculated by
@@ -334,11 +338,12 @@
     iniset ${SWIFT_CONFIG_PROXY_SERVER} app:proxy-server node_timeout 120
     iniset ${SWIFT_CONFIG_PROXY_SERVER} app:proxy-server conn_timeout 20
 
-    # Configure Ceilometer
-    if is_service_enabled ceilometer; then
-        iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:ceilometer use "egg:ceilometer#swift"
-        SWIFT_EXTRAS_MIDDLEWARE_LAST="${SWIFT_EXTRAS_MIDDLEWARE_LAST} ceilometer"
-    fi
+    # Skipped due to bug 1294789
+    ## Configure Ceilometer
+    #if is_service_enabled ceilometer; then
+    #    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:ceilometer use "egg:ceilometer#swift"
+    #    SWIFT_EXTRAS_MIDDLEWARE_LAST="${SWIFT_EXTRAS_MIDDLEWARE_LAST} ceilometer"
+    #fi
 
     # Restrict the length of auth tokens in the swift proxy-server logs.
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:proxy-logging reveal_sensitive_prefix ${SWIFT_LOG_TOKEN_LENGTH}
@@ -403,6 +408,7 @@
 
     cp ${SWIFT_DIR}/etc/swift.conf-sample ${SWIFT_CONF_DIR}/swift.conf
     iniset ${SWIFT_CONF_DIR}/swift.conf swift-hash swift_hash_path_suffix ${SWIFT_HASH}
+    iniset ${SWIFT_CONF_DIR}/swift.conf swift-constraints max_header_size ${SWIFT_MAX_HEADER_SIZE}
 
     for node_number in ${SWIFT_REPLICAS_SEQ}; do
         swift_node_config=${SWIFT_CONF_DIR}/object-server/${node_number}.conf
@@ -452,8 +458,14 @@
     rm -rf ${swift_log_dir}
     mkdir -p ${swift_log_dir}/hourly
     sudo chown -R ${STACK_USER}:adm ${swift_log_dir}
-    sed "s,%SWIFT_LOGDIR%,${swift_log_dir}," $FILES/swift/rsyslog.conf | sudo \
-        tee /etc/rsyslog.d/10-swift.conf
+
+    if [[ $SYSLOG != "False" ]]; then
+        sed "s,%SWIFT_LOGDIR%,${swift_log_dir}," $FILES/swift/rsyslog.conf | sudo \
+            tee /etc/rsyslog.d/10-swift.conf
+        # restart syslog to take the changes
+        sudo killall -HUP rsyslogd
+    fi
+
     if is_apache_enabled_service swift; then
         _config_swift_apache_wsgi
     fi
@@ -485,7 +497,7 @@
     truncate -s ${SWIFT_LOOPBACK_DISK_SIZE} ${SWIFT_DISK_IMAGE}
 
     # Make a fresh XFS filesystem
-    mkfs.xfs -f -i size=1024  ${SWIFT_DISK_IMAGE}
+    /sbin/mkfs.xfs -f -i size=1024  ${SWIFT_DISK_IMAGE}
 
     # Mount the disk with mount options to make it as efficient as possible
     mkdir -p ${SWIFT_DATA_DIR}/drives/sdb1
@@ -627,8 +639,6 @@
 
 # start_swift() - Start running processes, including screen
 function start_swift {
-    # (re)start rsyslog
-    restart_service rsyslog
     # (re)start memcached to make sure we have a clean memcache.
     restart_service memcached
 
diff --git a/lib/tempest b/lib/tempest
index d81423b..fb9971c 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -28,7 +28,6 @@
 # - ``DEFAULT_INSTANCE_TYPE``
 # - ``DEFAULT_INSTANCE_USER``
 # - ``CINDER_MULTI_LVM_BACKEND``
-# - ``HEAT_CREATE_TEST_IMAGE``
 #
 # ``stack.sh`` calls the entry points in this order:
 #
@@ -77,7 +76,6 @@
     local num_images
     local image_uuid
     local image_uuid_alt
-    local errexit
     local password
     local line
     local flavors
@@ -90,14 +88,6 @@
     local boto_instance_type="m1.tiny"
     local ssh_connect_method="fixed"
 
-    # TODO(afazekas):
-    # sudo python setup.py deploy
-
-    # This function exits on an error so that errors don't compound and you see
-    # only the first error that occurred.
-    errexit=$(set +o | grep errexit)
-    set -o errexit
-
     # Save IFS
     ifs=$IFS
 
@@ -153,6 +143,7 @@
     # user and tenant are set up...
     ADMIN_USERNAME=${ADMIN_USERNAME:-admin}
     ADMIN_TENANT_NAME=${ADMIN_TENANT_NAME:-admin}
+    ADMIN_DOMAIN_NAME=${ADMIN_DOMAIN_NAME:-Default}
     TEMPEST_USERNAME=${TEMPEST_USERNAME:-demo}
     TEMPEST_TENANT_NAME=${TEMPEST_TENANT_NAME:-demo}
     ALT_USERNAME=${ALT_USERNAME:-alt_demo}
@@ -267,6 +258,7 @@
     iniset $TEMPEST_CONFIG identity admin_username $ADMIN_USERNAME
     iniset $TEMPEST_CONFIG identity admin_password "$password"
     iniset $TEMPEST_CONFIG identity admin_tenant_name $ADMIN_TENANT_NAME
+    iniset $TEMPEST_CONFIG identity admin_domain_name $ADMIN_DOMAIN_NAME
     iniset $TEMPEST_CONFIG identity auth_version ${TEMPEST_AUTH_VERSION:-v2}
 
     # Image
@@ -277,7 +269,6 @@
     fi
 
     # Compute
-    iniset $TEMPEST_CONFIG compute change_password_available False
     iniset $TEMPEST_CONFIG compute allow_tenant_isolation ${TEMPEST_ALLOW_TENANT_ISOLATION:-True}
     iniset $TEMPEST_CONFIG compute ssh_user ${DEFAULT_INSTANCE_USER:-cirros} # DEPRECATED
     iniset $TEMPEST_CONFIG compute network_for_ssh $PRIVATE_NETWORK_NAME
@@ -289,10 +280,14 @@
     iniset $TEMPEST_CONFIG compute image_alt_ssh_user ${DEFAULT_INSTANCE_USER:-cirros}
     iniset $TEMPEST_CONFIG compute flavor_ref $flavor_ref
     iniset $TEMPEST_CONFIG compute flavor_ref_alt $flavor_ref_alt
-    iniset $TEMPEST_CONFIG compute live_migration_available ${LIVE_MIGRATION_AVAILABLE:-False}
-    iniset $TEMPEST_CONFIG compute use_block_migration_for_live_migration ${USE_BLOCK_MIGRATION_FOR_LIVE_MIGRATION:-False}
     iniset $TEMPEST_CONFIG compute ssh_connect_method $ssh_connect_method
 
+    # Compute Features
+    iniset $TEMPEST_CONFIG compute-feature-enabled resize True
+    iniset $TEMPEST_CONFIG compute-feature-enabled live_migration ${LIVE_MIGRATION_AVAILABLE:-False}
+    iniset $TEMPEST_CONFIG compute-feature-enabled change_password False
+    iniset $TEMPEST_CONFIG compute-feature-enabled block_migration_for_live_migration ${USE_BLOCK_MIGRATION_FOR_LIVE_MIGRATION:-False}
+
     # Compute admin
     iniset $TEMPEST_CONFIG "compute-admin" username $ADMIN_USERNAME
     iniset $TEMPEST_CONFIG "compute-admin" password "$password"
@@ -317,12 +312,18 @@
     iniset $TEMPEST_CONFIG boto http_socket_timeout 30
     iniset $TEMPEST_CONFIG boto ssh_user ${DEFAULT_INSTANCE_USER:-cirros}
 
-    # Orchestration test image
-    if [[ ! -z "$HEAT_FETCHED_TEST_IMAGE" ]]; then
-        iniset $TEMPEST_CONFIG orchestration image_ref "$HEAT_FETCHED_TEST_IMAGE"
-    elif [[ "$HEAT_CREATE_TEST_IMAGE" = "True" ]]; then
-        disk_image_create /usr/share/tripleo-image-elements "vm fedora heat-cfntools" "i386" "fedora-vm-heat-cfntools-tempest"
-        iniset $TEMPEST_CONFIG orchestration image_ref "fedora-vm-heat-cfntools-tempest"
+    # Orchestration Tests
+    if is_service_enabled heat; then
+        if [[ ! -z "$HEAT_CFN_IMAGE_URL" ]]; then
+            iniset $TEMPEST_CONFIG orchestration image_ref $(basename "$HEAT_CFN_IMAGE_URL" ".qcow2")
+        fi
+        # build a specialized heat flavor that is likely to be fast
+        available_flavors=$(nova flavor-list)
+        if [[ ! ( $available_flavors =~ 'm1.heat' ) ]]; then
+            nova flavor-create m1.heat 451 1024 0 2
+        fi
+        iniset $TEMPEST_CONFIG orchestration instance_type "m1.heat"
+        iniset $TEMPEST_CONFIG orchestration build_timeout 900
     fi
 
     # Scenario
@@ -360,6 +361,11 @@
     # Networking
     iniset $TEMPEST_CONFIG network-feature-enabled api_extensions "${NETWORK_API_EXTENSIONS:-all}"
 
+    # Baremetal
+    if [ "$VIRT_DRIVER" = "ironic" ] ; then
+        iniset $TEMPEST_CONFIG baremetal driver_enabled True
+    fi
+
     # service_available
     for service in ${TEMPEST_SERVICES//,/ }; do
         if is_service_enabled $service ; then
@@ -371,8 +377,6 @@
 
     # Restore IFS
     IFS=$ifs
-    #Restore errexit
-    $errexit
 }
 
 # create_tempest_accounts() - Set up common required tempest accounts
@@ -402,6 +406,7 @@
 # install_tempest() - Collect source and prepare
 function install_tempest {
     git_clone $TEMPEST_REPO $TEMPEST_DIR $TEMPEST_BRANCH
+    pip_install "tox<1.7"
 }
 
 # init_tempest() - Initialize ec2 images
@@ -419,9 +424,9 @@
         ( #new namespace
             # tenant:demo ; user: demo
             source $TOP_DIR/accrc/demo/demo
-            euca-bundle-image -i "$kernel" --kernel true -d "$BOTO_MATERIALS_PATH"
-            euca-bundle-image -i "$ramdisk" --ramdisk true -d "$BOTO_MATERIALS_PATH"
-            euca-bundle-image -i "$disk_image" -d "$BOTO_MATERIALS_PATH"
+            euca-bundle-image -r x86_64 -i "$kernel" --kernel true -d "$BOTO_MATERIALS_PATH"
+            euca-bundle-image -r x86_64 -i "$ramdisk" --ramdisk true -d "$BOTO_MATERIALS_PATH"
+            euca-bundle-image -r x86_64 -i "$disk_image" -d "$BOTO_MATERIALS_PATH"
         ) 2>&1 </dev/null | cat
     else
         echo "Boto materials are not prepared"
diff --git a/lib/tls b/lib/tls
index 072059d..88e5f60 100644
--- a/lib/tls
+++ b/lib/tls
@@ -348,7 +348,7 @@
     local key=${!key_var}
     local ca=${!ca_var}
 
-    if [[ !($cert && $key && $ca) ]]; then
+    if [[ -z "$cert" || -z "$key" || -z "$ca" ]]; then
         die $LINENO "Missing either the ${cert_var} ${key_var} or ${ca_var}" \
                     "variable to enable SSL for ${service}"
     fi
diff --git a/lib/trove b/lib/trove
index 75b990f..8631470 100644
--- a/lib/trove
+++ b/lib/trove
@@ -21,8 +21,11 @@
 
 # Defaults
 # --------
-
-NETWORK_GATEWAY=${NETWORK_GATEWAY:-10.0.0.1}
+if is_service_enabled neutron; then
+    TROVE_HOST_GATEWAY=${PUBLIC_NETWORK_GATEWAY:-172.24.4.1}
+else
+    TROVE_HOST_GATEWAY=${NETWORK_GATEWAY:-10.0.0.1}
+fi
 
 # Set up default configuration
 TROVE_DIR=$DEST/trove
@@ -147,9 +150,12 @@
     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_CONF_DIR/trove.conf DEFAULT nova_compute_url $NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2
+    iniset $TROVE_CONF_DIR/trove.conf DEFAULT cinder_url $CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1
+    iniset $TROVE_CONF_DIR/trove.conf DEFAULT swift_url http://$SERVICE_HOST:8080/v1/AUTH_
 
     iniset $TROVE_LOCAL_CONF_DIR/trove-guestagent.conf.sample DEFAULT rabbit_password $RABBIT_PASSWORD
-    sed -i "s/localhost/$NETWORK_GATEWAY/g" $TROVE_LOCAL_CONF_DIR/trove-guestagent.conf.sample
+    sed -i "s/localhost/$TROVE_HOST_GATEWAY/g" $TROVE_LOCAL_CONF_DIR/trove-guestagent.conf.sample
 
     setup_trove_logging $TROVE_CONF_DIR/trove.conf
     setup_trove_logging $TROVE_LOCAL_CONF_DIR/trove-guestagent.conf.sample
@@ -164,6 +170,9 @@
         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 nova_compute_url $NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2
+        iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT cinder_url $CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v1
+        iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT swift_url http://$SERVICE_HOST:8080/v1/AUTH_
         iniset $TROVE_CONF_DIR/trove-taskmanager.conf DEFAULT trove_auth_url $TROVE_AUTH_ENDPOINT
         setup_trove_logging $TROVE_CONF_DIR/trove-taskmanager.conf
     fi
diff --git a/run_tests.sh b/run_tests.sh
index 685b203..b1aef4f 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -15,6 +15,23 @@
 #
 # this runs a series of unit tests for devstack to ensure it's functioning
 
+PASSES=""
+FAILURES=""
+
+# Check the return code and add the test to PASSES or FAILURES as appropriate
+# pass_fail <result> <expected> <name>
+function pass_fail {
+    local result=$1
+    local expected=$2
+    local test_name=$3
+
+    if [[ $result -ne $expected ]]; then
+        FAILURES="$FAILURES $test_name"
+    else
+        PASSES="$PASSES $test_name"
+    fi
+}
+
 if [[ -n $@ ]]; then
     FILES=$@
 else
@@ -27,6 +44,7 @@
 echo "Running bash8..."
 
 ./tools/bash8.py -v $FILES
+pass_fail $? 0 bash8
 
 
 # Test that no one is trying to land crazy refs as branches
@@ -35,8 +53,21 @@
 
 REFS=`grep BRANCH stackrc | grep -v -- '-master'`
 rc=$?
+pass_fail $rc 1 crazy-refs
 if [[ $rc -eq 0 ]]; then
     echo "Branch defaults must be master. Found:"
     echo $REFS
+fi
+
+echo "====================================================================="
+for script in $PASSES; do
+    echo PASS $script
+done
+for script in $FAILURES; do
+    echo FAILED $script
+done
+echo "====================================================================="
+
+if [[ -n "$FAILURES" ]]; then
     exit 1
 fi
diff --git a/stack.sh b/stack.sh
index a67f688..8fb57c4 100755
--- a/stack.sh
+++ b/stack.sh
@@ -149,6 +149,14 @@
     fi
 fi
 
+# Look for obsolete stuff
+if [[ ,${ENABLED_SERVICES}, =~ ,"swift", ]]; then
+    echo "FATAL: 'swift' is not supported as a service name"
+    echo "FATAL: Use the actual swift service names to enable tham as required:"
+    echo "FATAL: s-proxy s-object s-container s-account"
+    exit 1
+fi
+
 # Make sure we only have one rpc backend enabled,
 # and the specified rpc backend is available on your platform.
 check_rpc_backend
@@ -195,6 +203,7 @@
 # Some binaries might be under /sbin or /usr/sbin, so make sure sudo will
 # see them by forcing PATH
 echo "Defaults:$STACK_USER secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE
+echo "Defaults:$STACK_USER !requiretty" >> $TEMPFILE
 chmod 0440 $TEMPFILE
 sudo chown root:root $TEMPFILE
 sudo mv $TEMPFILE /etc/sudoers.d/50_stack_sh
@@ -214,21 +223,24 @@
     apt_get install --force-yes gplhost-archive-keyring
 fi
 
-if [[ is_fedora && $DISTRO =~ (rhel6) ]]; then
-    # Installing Open vSwitch on RHEL6 requires enabling the RDO repo.
-    RHEL6_RDO_REPO_RPM=${RHEL6_RDO_REPO_RPM:-"http://rdo.fedorapeople.org/openstack-havana/rdo-release-havana.rpm"}
-    RHEL6_RDO_REPO_ID=${RHEL6_RDO_REPO_ID:-"openstack-havana"}
+if [[ is_fedora && $DISTRO =~ (rhel) ]]; then
+    # Installing Open vSwitch on RHEL requires enabling the RDO repo.
+    RHEL6_RDO_REPO_RPM=${RHEL6_RDO_REPO_RPM:-"http://rdo.fedorapeople.org/openstack-icehouse/rdo-release-icehouse.rpm"}
+    RHEL6_RDO_REPO_ID=${RHEL6_RDO_REPO_ID:-"openstack-icehouse"}
     if ! sudo yum repolist enabled $RHEL6_RDO_REPO_ID | grep -q $RHEL6_RDO_REPO_ID; then
         echo "RDO repo not detected; installing"
         yum_install $RHEL6_RDO_REPO_RPM || \
             die $LINENO "Error installing RDO repo, cannot continue"
     fi
-
-    # RHEL6 requires EPEL for many Open Stack dependencies
-    RHEL6_EPEL_RPM=${RHEL6_EPEL_RPM:-"http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm"}
+    # RHEL requires EPEL for many Open Stack dependencies
+    if [[ $DISTRO =~ (rhel7) ]]; then
+        EPEL_RPM=${RHEL7_EPEL_RPM:-"http://dl.fedoraproject.org/pub/epel/beta/7/x86_64/epel-release-7-0.1.noarch.rpm"}
+    else
+        EPEL_RPM=${RHEL6_EPEL_RPM:-"http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm"}
+    fi
     if ! sudo yum repolist enabled epel | grep -q 'epel'; then
         echo "EPEL not detected; installing"
-        yum_install ${RHEL6_EPEL_RPM} || \
+        yum_install ${EPEL_RPM} || \
             die $LINENO "Error installing EPEL repo, cannot continue"
     fi
 
@@ -289,7 +301,7 @@
 
 HOST_IP=$(get_default_host_ip $FIXED_RANGE $FLOATING_RANGE "$HOST_IP_IFACE" "$HOST_IP")
 if [ "$HOST_IP" == "" ]; then
-    die $LINENO "Could not determine host ip address. Either localrc specified dhcp on ${HOST_IP_IFACE} or defaulted"
+    die $LINENO "Could not determine host ip address.  See local.conf for suggestions on setting HOST_IP."
 fi
 
 # Allow the use of an alternate hostname (such as localhost/127.0.0.1) for service endpoints.
@@ -398,7 +410,7 @@
             echo "Invalid chars in password.  Try again:"
         done
         if [ ! $pw ]; then
-            pw=`openssl rand -hex 10`
+            pw=$(cat /dev/urandom | tr -cd 'a-f0-9' | head -c 20)
         fi
         eval "$var=$pw"
         echo "$var=$pw" >> $localrc
@@ -424,7 +436,7 @@
 
 # Rabbit connection info
 if is_service_enabled rabbit; then
-    RABBIT_HOST=${RABBIT_HOST:-localhost}
+    RABBIT_HOST=${RABBIT_HOST:-$SERVICE_HOST}
     read_password RABBIT_PASSWORD "ENTER A PASSWORD TO USE FOR RABBIT."
 fi
 
@@ -482,14 +494,18 @@
     done
 }
 
+function kill_spinner {
+    if [ ! -z "$LAST_SPINNER_PID" ]; then
+        kill >/dev/null 2>&1 $LAST_SPINNER_PID
+        printf "\b\b\bdone\n" >&3
+    fi
+}
+
 # Echo text to the log file, summary log file and stdout
 # echo_summary "something to say"
 function echo_summary {
     if [[ -t 3 && "$VERBOSE" != "True" ]]; then
-        kill >/dev/null 2>&1 $LAST_SPINNER_PID
-        if [ ! -z "$LAST_SPINNER_PID" ]; then
-            printf "\b\b\bdone\n" >&3
-        fi
+        kill_spinner
         echo -n -e $@ >&6
         spinner &
         LAST_SPINNER_PID=$!
@@ -527,10 +543,11 @@
 
     # Redirect output according to config
 
-    # Copy stdout to fd 3
+    # Set fd 3 to a copy of stdout. So we can set fd 1 without losing
+    # stdout later.
     exec 3>&1
     if [[ "$VERBOSE" == "True" ]]; then
-        # Redirect stdout/stderr to tee to write the log file
+        # Set fd 1 and 2 to write the log file
         exec 1> >( awk -v logfile=${LOGFILE} '
                 /((set \+o$)|xtrace)/ { next }
                 {
@@ -543,7 +560,7 @@
                     print
                     fflush("")
                 }' ) 2>&1
-        # Set up a second fd for output
+        # Set fd 6 to summary log file
         exec 6> >( tee "${SUMFILE}" )
     else
         # Set fd 1 and 2 to primary logfile
@@ -558,7 +575,8 @@
     ln -sf $SUMFILE $LOGDIR/$LOGFILENAME.summary
 else
     # Set up output redirection without log files
-    # Copy stdout to fd 3
+    # Set fd 3 to a copy of stdout. So we can set fd 1 without losing
+    # stdout later.
     exec 3>&1
     if [[ "$VERBOSE" != "True" ]]; then
         # Throw away stdout and stderr
@@ -594,10 +612,16 @@
 function exit_trap {
     local r=$?
     jobs=$(jobs -p)
-    if [[ -n $jobs ]]; then
+    # Only do the kill when we're logging through a process substitution,
+    # which currently is only to verbose logfile
+    if [[ -n $jobs && -n "$LOGFILE" && "$VERBOSE" == "True" ]]; then
         echo "exit_trap: cleaning up child processes"
         kill 2>&1 $jobs
     fi
+
+    # Kill the last spinner process
+    kill_spinner
+
     exit $r
 }
 
@@ -881,7 +905,7 @@
 # -------
 
 # A better kind of sysstat, with the top process per time slice
-DSTAT_OPTS="-tcndylp --top-cpu-adv"
+DSTAT_OPTS="-tcmndrylp --top-cpu-adv"
 if [[ -n ${SCREEN_LOGDIR} ]]; then
     screen_it dstat "cd $TOP_DIR; dstat $DSTAT_OPTS | tee $SCREEN_LOGDIR/$DSTAT_FILE"
 else
@@ -998,9 +1022,13 @@
     fi
 
     clean_iptables
-    rm -rf ${NOVA_STATE_PATH}/networks
-    sudo mkdir -p ${NOVA_STATE_PATH}/networks
-    safe_chown -R ${USER} ${NOVA_STATE_PATH}/networks
+
+    if is_service_enabled n-net; then
+        rm -rf ${NOVA_STATE_PATH}/networks
+        sudo mkdir -p ${NOVA_STATE_PATH}/networks
+        safe_chown -R ${USER} ${NOVA_STATE_PATH}/networks
+    fi
+
     # Force IP forwarding on, just in case
     sudo sysctl -w net.ipv4.ip_forward=1
 fi
diff --git a/stackrc b/stackrc
index dd52161..6dea983 100644
--- a/stackrc
+++ b/stackrc
@@ -21,9 +21,9 @@
 
 # Specify which services to launch.  These generally correspond to
 # screen tabs. To change the default list, use the ``enable_service`` and
-# ``disable_service`` functions in ``localrc``.
-# For example, to enable Swift add this to ``localrc``:
-#  enable_service swift
+# ``disable_service`` functions in ``local.conf``.
+# For example, to enable Swift add this to ``local.conf``:
+#  enable_service s-proxy s-object s-container s-account
 # In order to enable Neutron (a single node setup) add the following
 # settings in `` localrc``:
 #  disable_service n-net
@@ -32,7 +32,6 @@
 #  enable_service q-dhcp
 #  enable_service q-l3
 #  enable_service q-meta
-#  enable_service neutron
 #  # Optional, to enable tempest configuration as part of devstack
 #  enable_service tempest
 
@@ -213,7 +212,7 @@
 # storage service
 SWIFT_REPO=${SWIFT_REPO:-${GIT_BASE}/openstack/swift.git}
 SWIFT_BRANCH=${SWIFT_BRANCH:-master}
-SWIFT3_REPO=${SWIFT3_REPO:-http://github.com/fujita/swift3.git}
+SWIFT3_REPO=${SWIFT3_REPO:-${GIT_BASE}/stackforge/swift3.git}
 SWIFT3_BRANCH=${SWIFT3_BRANCH:-master}
 
 # python swift client library
@@ -226,8 +225,8 @@
 
 
 # diskimage-builder
-BM_IMAGE_BUILD_REPO=${BM_IMAGE_BUILD_REPO:-${GIT_BASE}/openstack/diskimage-builder.git}
-BM_IMAGE_BUILD_BRANCH=${BM_IMAGE_BUILD_BRANCH:-master}
+DIB_REPO=${DIB_REPO:-${GIT_BASE}/openstack/diskimage-builder.git}
+DIB_BRANCH=${DIB_BRANCH:-master}
 
 # a websockets/html5 or flash powered VNC console for vm instances
 NOVNC_REPO=${NOVNC_REPO:-https://github.com/kanaka/noVNC.git}
@@ -333,8 +332,8 @@
         esac
         ;;
     vsphere)
-        DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-debian-2.6.32-i686}
-        IMAGE_URLS=${IMAGE_URLS:-"http://partnerweb.vmware.com/programs/vmdkimage/cirros-0.3.0-i386-disk.vmdk"};;
+        DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-0.3.2-i386-disk.vmdk}
+        IMAGE_URLS=${IMAGE_URLS:-"http://partnerweb.vmware.com/programs/vmdkimage/cirros-0.3.2-i386-disk.vmdk"};;
     xenserver)
         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"};;
@@ -343,9 +342,23 @@
         IMAGE_URLS=${IMAGE_URLS:-"http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-uec.tar.gz"};;
 esac
 
-HEAT_FETCHED_TEST_IMAGE=${HEAT_FETCHED_TEST_IMAGE:-""}
-if [[ "$HEAT_FETCHED_TEST_IMAGE" == "Fedora-i386-20-20131211.1-sda" ]]; then
-    IMAGE_URLS+=",https://dl.fedoraproject.org/pub/fedora/linux/releases/20/Images/i386/$HEAT_FETCHED_TEST_IMAGE.qcow2"
+# Use 64bit fedora image if heat is enabled
+if [[ "$ENABLED_SERVICES" =~ 'h-api' ]]; then
+    case "$VIRT_DRIVER" in
+        libvirt|baremetal|ironic)
+            HEAT_CFN_IMAGE_URL=${HEAT_CFN_IMAGE_URL:-"https://dl.fedoraproject.org/pub/fedora/linux/releases/20/Images/x86_64/Fedora-x86_64-20-20131211.1-sda.qcow2"}
+            IMAGE_URLS+=",$HEAT_CFN_IMAGE_URL"
+            ;;
+        *)
+            ;;
+    esac
+fi
+# Staging Area for New Images, have them here for at least 24hrs for nodepool
+# to cache them otherwise the failure rates in the gate are too high
+PRECACHE_IMAGES=$(trueorfalse False $PRECACHE_IMAGES)
+if [[ "$PRECACHE_IMAGES" == "True" ]]; then
+    # staging in update for nodepool
+    IMAGE_URLS+=",https://dl.fedoraproject.org/pub/fedora/linux/updates/20/Images/x86_64/Fedora-x86_64-20-20140407-sda.qcow2"
 fi
 
 # 10Gb default volume backing file size
diff --git a/tools/build_docs.sh b/tools/build_docs.sh
index c566e63..384b1fa 100755
--- a/tools/build_docs.sh
+++ b/tools/build_docs.sh
@@ -22,7 +22,7 @@
 # --------
 
 # Source repo/branch for DevStack
-MASTER_REPO=${MASTER_REPO:-https://github.com/openstack-dev/devstack.git}
+MASTER_REPO=${MASTER_REPO:-git://git.openstack.org/openstack-dev/devstack}
 MASTER_BRANCH=${MASTER_BRANCH:-master}
 
 # http://devstack.org is a GitHub gh-pages site in the https://github.com/cloudbuilders/devtack.git repo
diff --git a/tools/create_userrc.sh b/tools/create_userrc.sh
index 47da334..5c1c329 100755
--- a/tools/create_userrc.sh
+++ b/tools/create_userrc.sh
@@ -34,7 +34,7 @@
 -P include password to the rc files; with -A it assume all users password is the same
 -A try with all user
 -u <username> create files just for the specified user
--C <tanent_name> create user and tenant, the specifid tenant will be the user's tenant
+-C <tenant_name> create user and tenant, the specifid tenant will be the user's tenant
 -r <name> when combined with -C and the (-u) user exists it will be the user's tenant role in the (-C)tenant (default: Member)
 -p <userpass> password for the user
 --os-username <username>
@@ -62,8 +62,8 @@
 
 # The services users usually in the service tenant.
 # rc files for service users, is out of scope.
-# Supporting different tanent for services is out of scope.
-SKIP_TENANT=",service," # tenant names are between commas(,)
+# Supporting different tenant for services is out of scope.
+SKIP_TENANT="service"
 MODE=""
 ROLE=Member
 USER_NAME=""
@@ -126,15 +126,15 @@
 
 export -n SERVICE_TOKEN SERVICE_ENDPOINT OS_SERVICE_TOKEN OS_SERVICE_ENDPOINT
 
-EC2_URL=http://localhost:8773/service/Cloud
-S3_URL=http://localhost:3333
+EC2_URL=`openstack endpoint show ec2 | grep " ec2.publicURL " | cut -d " " -f4`
+if [[ -z $EC2_URL ]]; then
+    EC2_URL=http://localhost:8773/service/Cloud
+fi
 
-ec2=`keystone endpoint-get --service ec2 | awk '/\|[[:space:]]*ec2.publicURL/ {print $4}'`
-[ -n "$ec2" ] && EC2_URL=$ec2
-
-s3=`keystone endpoint-get --service s3 | awk '/\|[[:space:]]*s3.publicURL/ {print $4}'`
-[ -n "$s3" ] && S3_URL=$s3
-
+S3_URL=`openstack endpoint show s3 | grep " s3.publicURL " | cut -d " " -f4`
+if [[ -z $S3_URL ]]; then
+    S3_URL=http://localhost:3333
+fi
 
 mkdir -p "$ACCOUNT_DIR"
 ACCOUNT_DIR=`readlink -f "$ACCOUNT_DIR"`
@@ -158,13 +158,13 @@
     local user_passwd=$5
 
     # The admin user can see all user's secret AWS keys, it does not looks good
-    local line=`keystone ec2-credentials-list --user_id $user_id | grep -E "^\\|[[:space:]]*($tenant_name|$tenant_id)[[:space:]]*\\|" | head -n 1`
+    local line=`openstack ec2 credentials list --user $user_id | grep " $tenant_id "`
     if [ -z "$line" ]; then
-        keystone ec2-credentials-create --user-id $user_id --tenant-id $tenant_id 1>&2
-        line=`keystone ec2-credentials-list --user_id $user_id | grep -E "^\\|[[:space:]]*($tenant_name|$tenant_id)[[:space:]]*\\|" | head -n 1`
+        openstack ec2 credentials create --user $user_id --project $tenant_id 1>&2
+        line=`openstack ec2 credentials list --user $user_id | grep " $tenant_id "`
     fi
     local ec2_access_key ec2_secret_key
-    read ec2_access_key ec2_secret_key <<<  `echo $line | awk '{print $4 " " $6 }'`
+    read ec2_access_key ec2_secret_key <<<  `echo $line | awk '{print $2 " " $4 }'`
     mkdir -p "$ACCOUNT_DIR/$tenant_name"
     local rcfile="$ACCOUNT_DIR/$tenant_name/$user_name"
     # The certs subject part are the tenant ID "dash" user ID, but the CN should be the first part of the DN
@@ -212,41 +212,35 @@
 }
 
 #admin users expected
-function create_or_get_tenant {
-    local tenant_name=$1
-    local tenant_id=`keystone tenant-list | awk '/\|[[:space:]]*'"$tenant_name"'[[:space:]]*\|.*\|/ {print $2}'`
-    if [ -n "$tenant_id" ]; then
-        echo $tenant_id
-    else
-        keystone tenant-create --name "$tenant_name" | awk '/\|[[:space:]]*id[[:space:]]*\|.*\|/ {print $4}'
+function create_or_get_project {
+    local name=$1
+    local id
+    eval $(openstack project show -f shell -c id $name)
+    if [[ -z $id ]]; then
+        eval $(openstack project create -f shell -c id $name)
     fi
+    echo $id
 }
 
 function create_or_get_role {
-    local role_name=$1
-    local role_id=`keystone role-list| awk '/\|[[:space:]]*'"$role_name"'[[:space:]]*\|/ {print $2}'`
-    if [ -n "$role_id" ]; then
-        echo $role_id
-    else
-        keystone role-create --name "$role_name" |awk '/\|[[:space:]]*id[[:space:]]*\|.*\|/ {print $4}'
+    local name=$1
+    local id
+    eval $(openstack role show -f shell -c id $name)
+    if [[ -z $id ]]; then
+        eval $(openstack role create -f shell -c id $name)
     fi
+    echo $id
 }
 
 # Provides empty string when the user does not exists
 function get_user_id {
-    local user_name=$1
-    keystone user-list | awk '/^\|[^|]*\|[[:space:]]*'"$user_name"'[[:space:]]*\|.*\|/ {print $2}'
+    openstack user list | grep " $1 " | cut -d " " -f2
 }
 
 if [ $MODE != "create" ]; then
-# looks like I can't ask for all tenant related to a specified  user
-    for tenant_id_at_name in `keystone tenant-list | awk 'BEGIN {IGNORECASE = 1} /true[[:space:]]*\|$/ {print  $2 "@" $4}'`; do
-        read tenant_id tenant_name <<< `echo "$tenant_id_at_name" | sed 's/@/ /'`
-        if echo $SKIP_TENANT| grep -q ",$tenant_name,"; then
-            continue;
-        fi
-        for user_id_at_name in `keystone user-list --tenant-id $tenant_id | awk 'BEGIN {IGNORECASE = 1} /true[[:space:]]*\|[^|]*\|$/ {print  $2 "@" $4}'`; do
-            read user_id user_name <<< `echo "$user_id_at_name" | sed 's/@/ /'`
+# looks like I can't ask for all tenant related to a specified user
+    openstack project list --long --quote none -f csv | grep ',True' | grep -v "${SKIP_TENANT}" | while IFS=, read tenant_id tenant_name desc enabled; do
+        openstack user list --project $tenant_id --long --quote none -f csv | grep ',True' | while IFS=, read user_id user_name project email enabled; do
             if [ $MODE = one -a "$user_name" != "$USER_NAME" ]; then
                 continue;
             fi
@@ -263,18 +257,16 @@
     done
 else
     tenant_name=$TENANT
-    tenant_id=`create_or_get_tenant "$TENANT"`
+    tenant_id=$(create_or_get_project "$TENANT")
     user_name=$USER_NAME
     user_id=`get_user_id $user_name`
     if [ -z "$user_id" ]; then
-        #new user
-        user_id=`keystone user-create --name "$user_name" --tenant-id "$tenant_id" --pass "$USER_PASS" --email "$user_name@example.com" | awk '/\|[[:space:]]*id[[:space:]]*\|.*\|/ {print $4}'`
-        #The password is in the cmd line. It is not a good thing
+        eval $(openstack user create "$user_name" --project "$tenant_id" --password "$USER_PASS" --email "$user_name@example.com" -f shell -c id)
+        user_id=$id
         add_entry "$user_id" "$user_name" "$tenant_id" "$tenant_name" "$USER_PASS"
     else
-        #new role
-        role_id=`create_or_get_role "$ROLE"`
-        keystone user-role-add --user-id "$user_id" --tenant-id "$tenant_id" --role-id "$role_id"
+        role_id=$(create_or_get_role "$ROLE")
+        openstack role add "$role_id" --user "$user_id" --project "$tenant_id"
         add_entry "$user_id" "$user_name" "$tenant_id" "$tenant_name" "$USER_PASS"
     fi
 fi
diff --git a/tools/fixup_stuff.sh b/tools/fixup_stuff.sh
index 7833278..e6a6a79 100755
--- a/tools/fixup_stuff.sh
+++ b/tools/fixup_stuff.sh
@@ -145,4 +145,11 @@
     # work unmolested.
     sudo ln -sf /usr/bin/nosetests1.1 /usr/local/bin/nosetests
 
+    # workaround for https://code.google.com/p/unittest-ext/issues/detail?id=79
+    install_package python-unittest2 patch
+    pip_install discover
+    (cd /usr/lib/python2.6/site-packages/; sudo patch <"$FILES/patches/unittest2-discover.patch" || echo 'Assume already applied')
+    # Make sure the discover.pyc is up to date
+    sudo rm /usr/lib/python2.6/site-packages/discover.pyc || true
+    sudo python -c 'import discover'
 fi
diff --git a/tools/image_list.sh b/tools/image_list.sh
new file mode 100755
index 0000000..f9a4e2f
--- /dev/null
+++ b/tools/image_list.sh
@@ -0,0 +1,36 @@
+#!/bin/bash
+
+# Keep track of the devstack directory
+TOP_DIR=$(cd $(dirname "$0")/.. && pwd)
+
+source $TOP_DIR/functions
+
+# Possible virt drivers, if we have more, add them here. Always keep
+# dummy in the end position to trigger the fall through case.
+DRIVERS="openvz ironic libvirt vsphere xenserver dummy"
+
+# Extra variables to trigger getting additional images.
+ENABLED_SERVICES=h-api
+HEAT_FETCHED_TEST_IMAGE="Fedora-i386-20-20131211.1-sda"
+PRECACHE_IMAGES=True
+
+# Loop over all the virt drivers and collect all the possible images
+ALL_IMAGES=""
+for driver in $DRIVERS; do
+    VIRT_DRIVER=$driver
+    URLS=$(source $TOP_DIR/stackrc && echo $IMAGE_URLS)
+    if [[ ! -z "$ALL_IMAGES" ]]; then
+        ALL_IMAGES+=,
+    fi
+    ALL_IMAGES+=$URLS
+done
+
+# Make a nice list
+echo $ALL_IMAGES | tr ',' '\n' | sort | uniq
+
+# Sanity check - ensure we have a minimum number of images
+num=$(echo $ALL_IMAGES | tr ',' '\n' | sort | uniq | wc -l)
+if [[ "$num" -lt 5 ]]; then
+    echo "ERROR: We only found $num images in $ALL_IMAGES, which can't be right."
+    exit 1
+fi
diff --git a/tools/install_pip.sh b/tools/install_pip.sh
index 9fa161e..1eb9e7a 100755
--- a/tools/install_pip.sh
+++ b/tools/install_pip.sh
@@ -71,12 +71,13 @@
 }
 
 function install_pip_tarball {
-    (cd $FILES; \
-        curl -O $PIP_TAR_URL; \
-        tar xvfz pip-$INSTALL_PIP_VERSION.tar.gz 1>/dev/null; \
-        cd pip-$INSTALL_PIP_VERSION; \
-        sudo -E python setup.py install 1>/dev/null; \
-    )
+    if [[ ! -r $FILES/pip-$INSTALL_PIP_VERSION.tar.gz ]]; then
+        (cd $FILES; \
+            curl -O $PIP_TAR_URL; \
+            tar xvfz pip-$INSTALL_PIP_VERSION.tar.gz 1>/dev/null)
+    fi
+    (cd $FILES/pip-$INSTALL_PIP_VERSION; \
+        sudo -E python setup.py install 1>/dev/null)
 }
 
 # Show starting versions
diff --git a/tools/ironic/scripts/cleanup-nodes b/tools/ironic/scripts/cleanup-nodes
index dc5a19d..adeca5c 100755
--- a/tools/ironic/scripts/cleanup-nodes
+++ b/tools/ironic/scripts/cleanup-nodes
@@ -8,10 +8,13 @@
 set -exu
 
 LIBVIRT_STORAGE_POOL=${LIBVIRT_STORAGE_POOL:-"default"}
+LIBVIRT_CONNECT_URI=${LIBVIRT_CONNECT_URI:-"qemu:///system"}
 
 VM_COUNT=$1
 NETWORK_BRIDGE=$2
 
+export VIRSH_DEFAULT_CONNECT_URI=$LIBVIRT_CONNECT_URI
+
 for (( idx=0; idx<$VM_COUNT; idx++ )); do
     NAME="baremetal${NETWORK_BRIDGE}_${idx}"
     VOL_NAME="baremetal${NETWORK_BRIDGE}-${idx}.qcow2"
diff --git a/tools/ironic/scripts/configure-vm b/tools/ironic/scripts/configure-vm
index 9936b76..4c42c49 100755
--- a/tools/ironic/scripts/configure-vm
+++ b/tools/ironic/scripts/configure-vm
@@ -9,6 +9,25 @@
                            'templates')
 
 
+CONSOLE_LOG = """
+    <serial type='file'>
+      <source path='%(console_log)s'/>
+      <target port='0'/>
+      <alias name='serial0'/>
+    </serial>
+    <serial type='pty'>
+      <source path='/dev/pts/49'/>
+      <target port='1'/>
+      <alias name='serial1'/>
+    </serial>
+    <console type='file'>
+      <source path='%(console_log)s'/>
+      <target type='serial' port='0'/>
+      <alias name='serial0'/>
+    </console>
+"""
+
+
 def main():
     parser = argparse.ArgumentParser(
         description="Configure a kvm virtual machine for the seed image.")
@@ -30,6 +49,8 @@
                         help='The libvirt network name to use')
     parser.add_argument('--libvirt-nic-driver', default='e1000',
                         help='The libvirt network driver to use')
+    parser.add_argument('--console-log',
+                        help='File to log console')
     parser.add_argument('--emulator', default=None,
                         help='Path to emulator bin for vm template')
     args = parser.parse_args()
@@ -44,6 +65,7 @@
         'cpus': args.cpus,
         'bootdev': args.bootdev,
         'network': args.network,
+        'nicdriver': args.libvirt_nic_driver,
         'emulator': args.emulator,
     }
 
@@ -55,22 +77,13 @@
         elif os.path.exists("/usr/bin/qemu-kvm"):  # Redhat
             params['emulator'] = "/usr/bin/qemu-kvm"
 
-    nicparams = {
-        'nicdriver': args.libvirt_nic_driver,
-        'network': args.network,
-    }
-
-    params['bm_network'] = """
-<!-- neutron friendly 'bare metal' network -->
-<interface type='network'>
-  <source network='%(network)s'/>
-  <virtualport type='openvswitch'/>
-  <model type='%(nicdriver)s'/>
-  <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
-</interface>""" % nicparams
-
+    if args.console_log:
+        params['console_log'] = CONSOLE_LOG % {'console_log': args.console_log}
+    else:
+        params['console_log'] = ''
     libvirt_template = source_template % params
     conn = libvirt.open("qemu:///system")
+
     a = conn.defineXML(libvirt_template)
     print ("Created machine %s with UUID %s" % (args.name, a.UUIDString()))
 
diff --git a/tools/ironic/scripts/create-nodes b/tools/ironic/scripts/create-nodes
index 3232b50..140bffe 100755
--- a/tools/ironic/scripts/create-nodes
+++ b/tools/ironic/scripts/create-nodes
@@ -4,7 +4,7 @@
 
 # Creates baremetal poseur nodes for ironic testing purposes
 
-set -exu
+set -ex
 
 # Keep track of the devstack directory
 TOP_DIR=$(cd $(dirname "$0")/.. && pwd)
@@ -24,9 +24,13 @@
 TOTAL=$(($5 - 1))
 BRIDGE=$6
 EMULATOR=$7
+LOGDIR=$8
 
 LIBVIRT_NIC_DRIVER=${LIBVIRT_NIC_DRIVER:-"e1000"}
 LIBVIRT_STORAGE_POOL=${LIBVIRT_STORAGE_POOL:-"default"}
+LIBVIRT_CONNECT_URI=${LIBVIRT_CONNECT_URI:-"qemu:///system"}
+
+export VIRSH_DEFAULT_CONNECT_URI=$LIBVIRT_CONNECT_URI
 
 if ! virsh pool-list --all | grep -q $LIBVIRT_STORAGE_POOL; then
     virsh pool-define-as --name $LIBVIRT_STORAGE_POOL dir --target /var/lib/libvirt/images >&2
@@ -40,6 +44,10 @@
   virsh pool-start $LIBVIRT_STORAGE_POOL >&2
 fi
 
+if [ -n "$LOGDIR" ] ; then
+  mkdir -p "$LOGDIR"
+fi
+
 PREALLOC=
 if [ -f /etc/debian_version ]; then
     PREALLOC="--prealloc-metadata"
@@ -48,6 +56,11 @@
 DOMS=""
 for idx in $(seq 0 $TOTAL) ; do
     NAME="baremetal${BRIDGE}_${idx}"
+    if [ -n "$LOGDIR" ] ; then
+      VM_LOGGING="--console-log $LOGDIR/${NAME}_console.log"
+    else
+      VM_LOGGING=""
+    fi
     DOMS="$DOMS $NAME"
     VOL_NAME="baremetal${BRIDGE}-${idx}.qcow2"
     (virsh list --all | grep -q $NAME) && continue
@@ -59,7 +72,10 @@
     # Pre-touch the VM to set +C, as it can only be set on empty files.
     sudo touch "$volume_path"
     sudo chattr +C "$volume_path" || true
-    $TOP_DIR/scripts/configure-vm --bootdev network --name $NAME --image "$volume_path" --arch $ARCH --cpus $CPU --memory $MEM --libvirt-nic-driver $LIBVIRT_NIC_DRIVER --emulator $EMULATOR --network $BRIDGE >&2
+    $TOP_DIR/scripts/configure-vm \
+      --bootdev network --name $NAME --image "$volume_path" \
+      --arch $ARCH --cpus $CPU --memory $MEM --libvirt-nic-driver $LIBVIRT_NIC_DRIVER \
+      --emulator $EMULATOR --network $BRIDGE $VM_LOGGING >&2
 done
 
 for dom in $DOMS ; do
diff --git a/tools/ironic/scripts/setup-network b/tools/ironic/scripts/setup-network
index 8c3ea90..e326bf8 100755
--- a/tools/ironic/scripts/setup-network
+++ b/tools/ironic/scripts/setup-network
@@ -7,11 +7,15 @@
 
 set -exu
 
+LIBVIRT_CONNECT_URI=${LIBVIRT_CONNECT_URI:-"qemu:///system"}
+
 # Keep track of the devstack directory
 TOP_DIR=$(cd $(dirname "$0")/.. && pwd)
 BRIDGE_SUFFIX=${1:-''}
 BRIDGE_NAME=brbm$BRIDGE_SUFFIX
 
+export VIRSH_DEFAULT_CONNECT_URI="$LIBVIRT_CONNECT_URI"
+
 # Only add bridge if missing
 (sudo ovs-vsctl list-br | grep ${BRIDGE_NAME}$) || sudo ovs-vsctl add-br ${BRIDGE_NAME}
 
diff --git a/tools/ironic/templates/tftpd-xinetd.template b/tools/ironic/templates/tftpd-xinetd.template
index 7b9b0f8..5f3d03f 100644
--- a/tools/ironic/templates/tftpd-xinetd.template
+++ b/tools/ironic/templates/tftpd-xinetd.template
@@ -8,4 +8,7 @@
   server          = /usr/sbin/in.tftpd
   server_args     = -v -v -v -v -v --map-file %TFTPBOOT_DIR%/map-file %TFTPBOOT_DIR%
   disable         = no
+  # This is a workaround for Fedora, where TFTP will listen only on
+  # IPv6 endpoint, if IPv4 flag is not used.
+  flags           = IPv4
 }
diff --git a/tools/ironic/templates/vm.xml b/tools/ironic/templates/vm.xml
index b18dec0..4f40334 100644
--- a/tools/ironic/templates/vm.xml
+++ b/tools/ironic/templates/vm.xml
@@ -27,14 +27,19 @@
     <controller type='ide' index='0'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
     </controller>
-    %(network)s
-    %(bm_network)s
+    <interface type='network'>
+      <source network='%(network)s'/>
+      <virtualport type='openvswitch'/>
+      <model type='%(nicdriver)s'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+    </interface>
     <input type='mouse' bus='ps2'/>
     <graphics type='vnc' port='-1' autoport='yes'/>
     <video>
       <model type='cirrus' vram='9216' heads='1'/>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
     </video>
+    %(console_log)s
     <memballoon model='virtio'>
       <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
     </memballoon>
diff --git a/tools/jenkins/jenkins_home/print_summary.py b/tools/jenkins/jenkins_home/print_summary.py
index ee3790f..8be500b 100755
--- a/tools/jenkins/jenkins_home/print_summary.py
+++ b/tools/jenkins/jenkins_home/print_summary.py
@@ -18,8 +18,8 @@
 
 
 def print_usage():
-    print ("Usage: %s [jenkins_url (eg. http://50.56.12.202:8080/)]"
-           % sys.argv[0])
+    print("Usage: %s [jenkins_url (eg. http://50.56.12.202:8080/)]"
+          % sys.argv[0])
     sys.exit()
 
 
diff --git a/tools/xen/scripts/install_ubuntu_template.sh b/tools/xen/scripts/install_ubuntu_template.sh
index d80ed09..d4d6567 100755
--- a/tools/xen/scripts/install_ubuntu_template.sh
+++ b/tools/xen/scripts/install_ubuntu_template.sh
@@ -14,6 +14,9 @@
 # This directory
 BASE_DIR=$(cd $(dirname "$0") && pwd)
 
+# Source the top level functions
+source $BASE_DIR/../../../functions
+
 # For default setings see xenrc
 source $BASE_DIR/../xenrc