Merge "docs: Add additional configuration in Neutron guide"
diff --git a/HACKING.rst b/HACKING.rst
index 6bd24b0..d763c75 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -250,8 +250,7 @@
   database access from the exercise itself.
 
 * If specific configuration needs to be present for the exercise to complete,
-  it should be staged in ``stack.sh``, or called from ``stack.sh`` (see
-  ``files/keystone_data.sh`` for an example of this).
+  it should be staged in ``stack.sh``, or called from ``stack.sh``.
 
 * The ``OS_*`` environment variables should be the only ones used for all
   authentication to OpenStack clients as documented in the CLIAuth_ wiki page.
@@ -329,7 +328,7 @@
 your change
 
 * **Is it passing tests** -- your change will not be reviewed
-  throughly unless the official CI has run successfully against it.
+  thoroughly unless the official CI has run successfully against it.
 
 * **Does this belong in DevStack** -- DevStack reviewers have a
   default position of "no" but are ready to be convinced by your
diff --git a/Makefile b/Makefile
index a6bb230..a94d60a 100644
--- a/Makefile
+++ b/Makefile
@@ -13,7 +13,6 @@
 
 # Duplicated from stackrc for now
 DEST=/opt/stack
-WHEELHOUSE=$(DEST)/.wheelhouse
 
 all:
 	echo "This just saved you from a terrible mistake!"
@@ -25,9 +24,6 @@
 unstack:
 	./unstack.sh
 
-wheels:
-	WHEELHOUSE=$(WHEELHOUSE) tools/build_wheels.sh
-
 docs:
 	tox -edocs
 
@@ -57,7 +53,7 @@
 
 # Clean out the cache too
 realclean: clean
-	rm -rf files/cirros*.tar.gz files/Fedora*.qcow2 $(WHEELHOUSE)
+	rm -rf files/cirros*.tar.gz files/Fedora*.qcow2
 
 # Repo stuffs
 
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index aae4f33..386fbbb 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -44,6 +44,7 @@
    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
@@ -202,8 +203,8 @@
 
         LOGDIR=$DEST/logs
 
-*Note the use of ``DEST`` to locate the main install directory; this
-is why we suggest setting it in ``local.conf``.*
+Note the use of ``DEST`` to locate the main install directory; this
+is why we suggest setting it in ``local.conf``.
 
 Enabling Syslog
 ~~~~~~~~~~~~~~~
@@ -211,7 +212,7 @@
 Logging all services to a single syslog can be convenient. Enable
 syslogging by setting ``SYSLOG`` to ``True``. If the destination log
 host is not localhost ``SYSLOG_HOST`` and ``SYSLOG_PORT`` can be used
-to direct the message stream to the log host.  |
+to direct the message stream to the log host.
 
     ::
 
@@ -239,15 +240,15 @@
 
 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:
+``mysql`` is the default database, choose a different one by putting the
+following in the ``localrc`` section:
 
    ::
 
       disable_service mysql
       enable_service postgresql
 
-`mysql` is the default database.
+``mysql`` is the default database.
 
 RPC Backend
 -----------
@@ -260,6 +261,7 @@
 Example disabling RabbitMQ in ``local.conf``:
 
 ::
+
     disable_service rabbit
 
 
@@ -297,6 +299,12 @@
 
     SWIFT_USE_MOD_WSGI="True"
 
+Example (Heat):
+
+::
+
+    HEAT_USE_MOD_WSGI="True"
+
 
 Example (Cinder):
 
@@ -387,7 +395,7 @@
         KEYSTONE_CATALOG_BACKEND=template
 
 DevStack's default configuration in ``sql`` mode is set in
-``files/keystone_data.sh``
+``lib/keystone``
 
 
 Guest Images
@@ -505,7 +513,7 @@
 object services will run directly in screen. The others services like
 replicator, updaters or auditor runs in background.
 
-If you would like to enable Swift you can add this to your `localrc`
+If you would like to enable Swift you can add this to your ``localrc``
 section:
 
 ::
@@ -513,7 +521,7 @@
     enable_service s-proxy s-object s-container s-account
 
 If you want a minimal Swift install with only Swift and Keystone you
-can have this instead in your `localrc` section:
+can have this instead in your ``localrc`` section:
 
 ::
 
@@ -522,24 +530,24 @@
 
 If you only want to do some testing of a real normal swift cluster
 with multiple replicas you can do so by customizing the variable
-`SWIFT_REPLICAS` in your `localrc` section (usually to 3).
+``SWIFT_REPLICAS`` in your ``localrc`` section (usually to 3).
 
 Swift S3
 ++++++++
 
-If you are enabling `swift3` in `ENABLED_SERVICES` DevStack will
+If you are enabling ``swift3`` in ``ENABLED_SERVICES`` DevStack will
 install the swift3 middleware emulation. Swift will be configured to
 act as a S3 endpoint for Keystone so effectively replacing the
-`nova-objectstore`.
+``nova-objectstore``.
 
 Only Swift proxy server is launched in the screen session all other
-services are started in background and managed by `swift-init` tool.
+services are started in background and managed by ``swift-init`` tool.
 
 Heat
 ~~~~
 
-Heat is disabled by default (see `stackrc` file). To enable it
-explicitly you'll need the following settings in your `localrc`
+Heat is disabled by default (see ``stackrc`` file). To enable it
+explicitly you'll need the following settings in your ``localrc``
 section
 
 ::
@@ -548,7 +556,7 @@
 
 Heat can also run in standalone mode, and be configured to orchestrate
 on an external OpenStack cloud. To launch only Heat in standalone mode
-you'll need the following settings in your `localrc` section
+you'll need the following settings in your ``localrc`` section
 
 ::
 
@@ -584,14 +592,14 @@
 ~~~~~~~~~
 
 If you would like to use Xenserver as the hypervisor, please refer to
-the instructions in `./tools/xen/README.md`.
+the instructions in ``./tools/xen/README.md``.
 
 Cells
 ~~~~~
 
 `Cells <http://wiki.openstack.org/blueprint-nova-compute-cells>`__ is
 an alternative scaling option.  To setup a cells environment add the
-following to your `localrc` section:
+following to your ``localrc`` section:
 
 ::
 
diff --git a/doc/source/faq.rst b/doc/source/faq.rst
index 3562bfa..7aca8d0 100644
--- a/doc/source/faq.rst
+++ b/doc/source/faq.rst
@@ -54,7 +54,7 @@
 releases other than those documented in ``README.md`` on a best-effort
 basis.
 
-Are there any differences between Ubuntu and Centos/Fedora support?
+Are there any differences between Ubuntu and CentOS/Fedora support?
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Both should work well and are tested by DevStack CI.
@@ -146,7 +146,7 @@
 
 
 Upstream DevStack is only tested with master and stable
-branches. Setting custom BRANCH definitions is not guarunteed to
+branches. Setting custom BRANCH definitions is not guaranteed to
 produce working results.
 
 What can I do about RabbitMQ not wanting to start on my fresh new VM?
diff --git a/doc/source/guides/devstack-with-lbaas-v2.rst b/doc/source/guides/devstack-with-lbaas-v2.rst
index f679783..f3bd2fe 100644
--- a/doc/source/guides/devstack-with-lbaas-v2.rst
+++ b/doc/source/guides/devstack-with-lbaas-v2.rst
@@ -1,13 +1,17 @@
-Configure Load-Balancer in Kilo
+Configure Load-Balancer Version 2
 =================================
 
-The Kilo release of OpenStack will support Version 2 of the neutron load balancer. Until now, using OpenStack `LBaaS V2 <http://docs.openstack.org/api/openstack-network/2.0/content/lbaas_ext.html>`_ has required a good understanding of neutron and LBaaS architecture and several manual steps.
+Starting in the OpenStack Liberty release, the
+`neutron LBaaS v2 API <http://developer.openstack.org/api-ref-networking-v2-ext.html>`_
+is now stable while the LBaaS v1 API has been deprecated.  The LBaaS v2 reference
+driver is based on Octavia.
 
 
 Phase 1: Create DevStack + 2 nova instances
 --------------------------------------------
 
-First, set up a vm of your choice with at least 8 GB RAM and 16 GB disk space, make sure it is updated. Install git and any other developer tools you find useful.
+First, set up a vm of your choice with at least 8 GB RAM and 16 GB disk space,
+make sure it is updated. Install git and any other developer tools you find useful.
 
 Install devstack
 
@@ -17,13 +21,14 @@
     cd devstack
 
 
-Edit your `local.conf` to look like
+Edit your ``local.conf`` to look like
 
   ::
 
     [[local|localrc]]
     # Load the external LBaaS plugin.
     enable_plugin neutron-lbaas https://git.openstack.org/openstack/neutron-lbaas
+    enable_plugin octavia https://git.openstack.org/openstack/octavia
 
     # ===== BEGIN localrc =====
     DATABASE_PASSWORD=password
@@ -42,13 +47,13 @@
     ENABLED_SERVICES+=,horizon
     # Nova
     ENABLED_SERVICES+=,n-api,n-crt,n-obj,n-cpu,n-cond,n-sch
-    IMAGE_URLS+=",https://launchpad.net/cirros/trunk/0.3.0/+download/cirros-0.3.0-x86_64-disk.img"
     # Glance
     ENABLED_SERVICES+=,g-api,g-reg
     # Neutron
     ENABLED_SERVICES+=,q-svc,q-agt,q-dhcp,q-l3,q-meta
-    # Enable LBaaS V2
+    # Enable LBaaS v2
     ENABLED_SERVICES+=,q-lbaasv2
+    ENABLED_SERVICES+=,octavia,o-cw,o-hk,o-hm,o-api
     # Cinder
     ENABLED_SERVICES+=,c-api,c-vol,c-sch
     # Tempest
@@ -69,11 +74,11 @@
   ::
 
     #create nova instances on private network
-    nova boot --image $(nova image-list | awk '/ cirros-0.3.0-x86_64-disk / {print $2}') --flavor 1 --nic net-id=$(neutron net-list | awk '/ private / {print $2}') node1
-    nova boot --image $(nova image-list | awk '/ cirros-0.3.0-x86_64-disk / {print $2}') --flavor 1 --nic net-id=$(neutron net-list | awk '/ private / {print $2}') node2
+    nova boot --image $(nova image-list | awk '/ cirros-.*-x86_64-uec / {print $2}') --flavor 1 --nic net-id=$(neutron net-list | awk '/ private / {print $2}') node1
+    nova boot --image $(nova image-list | awk '/ cirros-.*-x86_64-uec / {print $2}') --flavor 1 --nic net-id=$(neutron net-list | awk '/ private / {print $2}') node2
     nova list # should show the nova instances just created
 
-    #add secgroup rule to allow ssh etc..
+    #add secgroup rules to allow ssh etc..
     neutron security-group-rule-create default --protocol icmp
     neutron security-group-rule-create default --protocol tcp --port-range-min 22 --port-range-max 22
     neutron security-group-rule-create default --protocol tcp --port-range-min 80 --port-range-max 80
@@ -91,9 +96,16 @@
  ::
 
     neutron lbaas-loadbalancer-create --name lb1 private-subnet
+    neutron lbaas-loadbalancer-show lb1  # Wait for the provisioning_status to be ACTIVE.
     neutron lbaas-listener-create --loadbalancer lb1 --protocol HTTP --protocol-port 80 --name listener1
+    sleep 10  # Sleep since LBaaS actions can take a few seconds depending on the environment.
     neutron lbaas-pool-create --lb-algorithm ROUND_ROBIN --listener listener1 --protocol HTTP --name pool1
+    sleep 10
     neutron lbaas-member-create  --subnet private-subnet --address 10.0.0.3 --protocol-port 80 pool1
+    sleep 10
     neutron lbaas-member-create  --subnet private-subnet --address 10.0.0.5 --protocol-port 80 pool1
 
-Please note here that the "10.0.0.3" and "10.0.0.5" in the above commands are the IPs of the nodes (in my test run-thru, they were actually 10.2 and 10.4), and the address of the created LB will be reported as "vip_address" from the lbaas-loadbalancer-create, and a quick test of that LB is "curl that-lb-ip", which should alternate between showing the IPs of the two nodes.
+Please note here that the "10.0.0.3" and "10.0.0.5" in the above commands are the IPs of the nodes
+(in my test run-thru, they were actually 10.2 and 10.4), and the address of the created LB will be
+reported as "vip_address" from the lbaas-loadbalancer-create, and a quick test of that LB is
+"curl that-lb-ip", which should alternate between showing the IPs of the two nodes.
diff --git a/doc/source/guides/devstack-with-nested-kvm.rst b/doc/source/guides/devstack-with-nested-kvm.rst
index c652bac..85a5656 100644
--- a/doc/source/guides/devstack-with-nested-kvm.rst
+++ b/doc/source/guides/devstack-with-nested-kvm.rst
@@ -50,7 +50,7 @@
     parm:           nested:bool
 
 Start your VM, now it should have KVM capabilities -- you can verify
-that by ensuring `/dev/kvm` character device is present.
+that by ensuring ``/dev/kvm`` character device is present.
 
 
 Configure Nested KVM for AMD-based Machines
@@ -97,7 +97,7 @@
 Expose Virtualization Extensions to DevStack VM
 -----------------------------------------------
 
-Edit the VM's libvirt XML configuration via `virsh` utility:
+Edit the VM's libvirt XML configuration via ``virsh`` utility:
 
 ::
 
@@ -115,10 +115,10 @@
 -------------------------------
 
 Before invoking ``stack.sh`` in the VM, ensure that KVM is enabled. This
-can be verified by checking for the presence of the file `/dev/kvm` in
+can be verified by checking for the presence of the file ``/dev/kvm`` in
 your VM. If it is present, DevStack will default to using the config
-attribute `virt_type = kvm` in `/etc/nova.conf`; otherwise, it'll fall
-back to `virt_type=qemu`, i.e. plain QEMU emulation.
+attribute ``virt_type = kvm`` in ``/etc/nova.conf``; otherwise, it'll fall
+back to ``virt_type=qemu``, i.e. plain QEMU emulation.
 
 Optionally, to explicitly set the type of virtualization, to KVM, by the
 libvirt driver in nova, the below config attribute can be used in
@@ -131,7 +131,7 @@
 
 Once DevStack is configured successfully, verify if the Nova instances
 are using KVM by noticing the QEMU CLI invoked by Nova is using the
-parameter `accel=kvm`, e.g.:
+parameter ``accel=kvm``, e.g.:
 
 ::
 
diff --git a/doc/source/guides/neutron.rst b/doc/source/guides/neutron.rst
index c7a1153..a72b6f9 100644
--- a/doc/source/guides/neutron.rst
+++ b/doc/source/guides/neutron.rst
@@ -35,7 +35,7 @@
                 network hardware_network {
                         address = "172.18.161.0/24"
                         router [ address = "172.18.161.1" ];
-                        devstack_laptop [ address = "172.18.161.6" ];
+                        devstack-1 [ address = "172.18.161.6" ];
                 }
         }
 
@@ -43,9 +43,13 @@
 DevStack Configuration
 ----------------------
 
+The following is a complete `local.conf` for the host named
+`devstack-1`. It will run all the API and services, as well as
+serving as a hypervisor for guest instances.
 
 ::
 
+        [[local|localrc]]
         HOST_IP=172.18.161.6
         SERVICE_HOST=172.18.161.6
         MYSQL_HOST=172.18.161.6
@@ -57,6 +61,12 @@
         SERVICE_PASSWORD=secrete
         SERVICE_TOKEN=secrete
 
+        # Do not use Nova-Network
+        disable_service n-net
+        # Enable Neutron
+        ENABLED_SERVICES+=,q-svc,q-dhcp,q-meta,q-agt,q-l3
+
+
         ## Neutron options
         Q_USE_SECGROUP=True
         FLOATING_RANGE="172.18.161.0/24"
@@ -71,6 +81,166 @@
         OVS_BRIDGE_MAPPINGS=public:br-ex
 
 
+Adding Additional Compute Nodes
+-------------------------------
+
+Let's suppose that after installing DevStack on the first host, you
+also want to do multinode testing and networking.
+
+Physical Network Setup
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. nwdiag::
+
+        nwdiag {
+                inet [ shape = cloud ];
+                router;
+                inet -- router;
+
+                network hardware_network {
+                        address = "172.18.161.0/24"
+                        router [ address = "172.18.161.1" ];
+                        devstack-1 [ address = "172.18.161.6" ];
+                        devstack-2 [ address = "172.18.161.7" ];
+                }
+        }
+
+
+After DevStack installs and configures Neutron, traffic from guest VMs
+flows out of `devstack-2` (the compute node) and is encapsulated in a
+VXLAN tunnel back to `devstack-1` (the control node) where the L3
+agent is running.
+
+::
+
+    stack@devstack-2:~/devstack$ sudo ovs-vsctl show
+    8992d965-0ba0-42fd-90e9-20ecc528bc29
+        Bridge br-int
+            fail_mode: secure
+            Port br-int
+                Interface br-int
+                    type: internal
+            Port patch-tun
+                Interface patch-tun
+                    type: patch
+                    options: {peer=patch-int}
+        Bridge br-tun
+            fail_mode: secure
+            Port "vxlan-c0a801f6"
+                Interface "vxlan-c0a801f6"
+                    type: vxlan
+                    options: {df_default="true", in_key=flow, local_ip="172.18.161.7", out_key=flow, remote_ip="172.18.161.6"}
+            Port patch-int
+                Interface patch-int
+                    type: patch
+                    options: {peer=patch-tun}
+            Port br-tun
+                Interface br-tun
+                    type: internal
+        ovs_version: "2.0.2"
+
+Open vSwitch on the control node, where the L3 agent runs, is
+configured to de-encapsulate traffic from compute nodes, then forward
+it over the `br-ex` bridge, where `eth0` is attached.
+
+::
+
+    stack@devstack-1:~/devstack$ sudo ovs-vsctl show
+    422adeea-48d1-4a1f-98b1-8e7239077964
+        Bridge br-tun
+            fail_mode: secure
+            Port br-tun
+                Interface br-tun
+                    type: internal
+            Port patch-int
+                Interface patch-int
+                    type: patch
+                    options: {peer=patch-tun}
+            Port "vxlan-c0a801d8"
+                Interface "vxlan-c0a801d8"
+                    type: vxlan
+                    options: {df_default="true", in_key=flow, local_ip="172.18.161.6", out_key=flow, remote_ip="172.18.161.7"}
+        Bridge br-ex
+            Port phy-br-ex
+                Interface phy-br-ex
+                    type: patch
+                    options: {peer=int-br-ex}
+            Port "eth0"
+                Interface "eth0"
+            Port br-ex
+                Interface br-ex
+                    type: internal
+        Bridge br-int
+            fail_mode: secure
+            Port "tapce66332d-ea"
+                tag: 1
+                Interface "tapce66332d-ea"
+                    type: internal
+            Port "qg-65e5a4b9-15"
+                tag: 2
+                Interface "qg-65e5a4b9-15"
+                    type: internal
+            Port "qr-33e5e471-88"
+                tag: 1
+                Interface "qr-33e5e471-88"
+                    type: internal
+            Port "qr-acbe9951-70"
+                tag: 1
+                Interface "qr-acbe9951-70"
+                    type: internal
+            Port br-int
+                Interface br-int
+                    type: internal
+            Port patch-tun
+                Interface patch-tun
+                    type: patch
+                    options: {peer=patch-int}
+            Port int-br-ex
+                Interface int-br-ex
+                    type: patch
+                    options: {peer=phy-br-ex}
+        ovs_version: "2.0.2"
+
+`br-int` is a bridge that the Open vSwitch mechanism driver creates,
+which is used as the "integration bridge" where ports are created, and
+plugged into the virtual switching fabric. `br-ex` is an OVS bridge
+that is used to connect physical ports (like `eth0`), so that floating
+IP traffic for tenants can be received from the physical network
+infrastructure (and the internet), and routed to tenant network ports.
+`br-tun` is a tunnel bridge that is used to connect OpenStack nodes
+(like `devstack-2`) together. This bridge is used so that tenant
+network traffic, using the VXLAN tunneling protocol, flows between
+each compute node where tenant instances run.
+
+
+
+DevStack Compute Configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The host `devstack-2` has a very minimal `local.conf`.
+
+::
+
+    [[local|localrc]]
+    HOST_IP=172.18.161.7
+    SERVICE_HOST=172.18.161.6
+    MYSQL_HOST=172.18.161.6
+    RABBIT_HOST=172.18.161.6
+    GLANCE_HOSTPORT=172.18.161.6:9292
+    ADMIN_PASSWORD=secrete
+    MYSQL_PASSWORD=secrete
+    RABBIT_PASSWORD=secrete
+    SERVICE_PASSWORD=secrete
+    SERVICE_TOKEN=secrete
+
+    ## Neutron options
+    PUBLIC_INTERFACE=eth0
+    ENABLED_SERVICES=n-cpu,rabbit,q-agt
+
+Network traffic from `eth0` on the compute nodes is then NAT'd by the
+controller node that runs Neutron's `neutron-l3-agent` and provides L3
+connectivity.
+
 
 Neutron Networking with Open vSwitch and Provider Networks
 ==========================================================
@@ -170,8 +340,8 @@
 **Compute Nodes**
 
 In this example, the nodes that will host guest instances will run
-the `neutron-openvswitch-agent` for network connectivity, as well as
-the compute service `nova-compute`.
+the ``neutron-openvswitch-agent`` for network connectivity, as well as
+the compute service ``nova-compute``.
 
 DevStack Configuration
 ----------------------
@@ -184,8 +354,6 @@
         HOST_IP=10.0.0.2
         SERVICE_HOST=10.0.0.2
         MYSQL_HOST=10.0.0.2
-        SERVICE_HOST=10.0.0.2
-        MYSQL_HOST=10.0.0.2
         RABBIT_HOST=10.0.0.2
         GLANCE_HOSTPORT=10.0.0.2:9292
         PUBLIC_INTERFACE=eth1
@@ -228,7 +396,7 @@
 allocated to you, so that you could access your instances from the
 public internet.
 
-The following is the DevStack configuration on 
+The following is the DevStack configuration on
 compute node 1.
 
 ::
@@ -236,8 +404,6 @@
         HOST_IP=10.0.0.3
         SERVICE_HOST=10.0.0.2
         MYSQL_HOST=10.0.0.2
-        SERVICE_HOST=10.0.0.2
-        MYSQL_HOST=10.0.0.2
         RABBIT_HOST=10.0.0.2
         GLANCE_HOSTPORT=10.0.0.2:9292
         ADMIN_PASSWORD=secrete
@@ -257,16 +423,16 @@
         Q_L3_ENABLED=False
 
 Compute node 2's configuration will be exactly the same, except
-`HOST_IP` will be `10.0.0.4`
+``HOST_IP`` will be ``10.0.0.4``
 
 When DevStack is configured to use provider networking (via
-`Q_USE_PROVIDER_NETWORKING` is True and `Q_L3_ENABLED` is False) -
+``Q_USE_PROVIDER_NETWORKING`` is True and ``Q_L3_ENABLED`` is False) -
 DevStack will automatically add the network interface defined in
-`PUBLIC_INTERFACE` to the `OVS_PHYSICAL_BRIDGE`
+``PUBLIC_INTERFACE`` to the ``OVS_PHYSICAL_BRIDGE``
 
 For example, with the above  configuration, a bridge is
-created, named `br-ex` which is managed by Open vSwitch, and the
-second interface on the compute node, `eth1` is attached to the
+created, named ``br-ex`` which is managed by Open vSwitch, and the
+second interface on the compute node, ``eth1`` is attached to the
 bridge, to forward traffic sent by guest VMs.
 
 Miscellaneous Tips
@@ -308,7 +474,7 @@
 ------------------------------------------------
 
 Extension drivers for the ML2 plugin are set with the variable
-`Q_ML2_PLUGIN_EXT_DRIVERS`, and includes the 'port_security' extension
+``Q_ML2_PLUGIN_EXT_DRIVERS``, and includes the 'port_security' extension
 by default. If you want to remove all the extension drivers (even
-'port_security'), set `Q_ML2_PLUGIN_EXT_DRIVERS` to blank.
+'port_security'), set ``Q_ML2_PLUGIN_EXT_DRIVERS`` to blank.
 
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 99e96b1..ec345c9 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -44,6 +44,18 @@
 
    We recommend at least a :ref:`minimal-configuration` be set up.
 
+#. Add Stack User
+
+   Devstack should be run as a non-root user with sudo enabled
+   (standard logins to cloud images such as "ubuntu" or "cloud-user"
+   are usually fine).
+
+   You can quickly create a separate `stack` user to run DevStack with
+
+   ::
+
+       devstack/tools/create-stack-user.sh; su stack
+
 #. Start the install
 
    ::
@@ -206,7 +218,6 @@
 
 * `tools/build\_docs.sh <tools/build_docs.sh.html>`__
 * `tools/build\_venv.sh <tools/build_venv.sh.html>`__
-* `tools/build\_wheels.sh <tools/build_wheels.sh.html>`__
 * `tools/create-stack-user.sh <tools/create-stack-user.sh.html>`__
 * `tools/create\_userrc.sh <tools/create_userrc.sh.html>`__
 * `tools/fixup\_stuff.sh <tools/fixup_stuff.sh.html>`__
diff --git a/doc/source/plugin-registry.rst b/doc/source/plugin-registry.rst
index 49b3a7f..c68d926 100644
--- a/doc/source/plugin-registry.rst
+++ b/doc/source/plugin-registry.rst
@@ -26,6 +26,8 @@
 +------------------+---------------------------------------------+--------------------+
 |ceilometer        |git://git.openstack.org/openstack/ceilometer | metering           |
 +------------------+---------------------------------------------+--------------------+
+|congress          |git://git.openstack.org/openstack/congress   | governance         |
++------------------+---------------------------------------------+--------------------+
 |gnocchi           |git://git.openstack.org/openstack/gnocchi    | metric             |
 +------------------+---------------------------------------------+--------------------+
 |magnum            |git://git.openstack.org/openstack/magnum     |                    |
diff --git a/doc/source/plugins.rst b/doc/source/plugins.rst
index 8bd3797..83e5609 100644
--- a/doc/source/plugins.rst
+++ b/doc/source/plugins.rst
@@ -19,7 +19,16 @@
 external repositories. The plugin interface assumes the following:
 
 An external git repository that includes a ``devstack/`` top level
-directory. Inside this directory there can be 2 files.
+directory. Inside this directory there can be 3 files.
+
+- ``override-defaults`` - a file containing global variables that
+  will be sourced before the lib/* files. This allows the plugin
+  to override the defaults that are otherwise set in the lib/*
+  files.
+
+  For example, override-defaults may export CINDER_ENABLED_BACKENDS
+  to include the plugin-specific storage backend and thus be able
+  to override the default lvm only storage backend for Cinder.
 
 - ``settings`` - a file containing global variables that will be
   sourced very early in the process. This is helpful if other plugins
@@ -38,7 +47,7 @@
 
 - ``plugin.sh`` - the actual plugin. It is executed by devstack at
   well defined points during a ``stack.sh`` run. The plugin.sh
-  internal structure is discussed bellow.
+  internal structure is discussed below.
 
 
 Plugins are registered by adding the following to the localrc section
diff --git a/exercises/client-args.sh b/exercises/client-args.sh
index c33ef44..7cfef1c 100755
--- a/exercises/client-args.sh
+++ b/exercises/client-args.sh
@@ -41,7 +41,6 @@
 unset NOVA_REGION_NAME
 unset NOVA_URL
 unset NOVA_USERNAME
-unset NOVA_VERSION
 
 # Save the known variables for later
 export x_TENANT_NAME=$OS_TENANT_NAME
diff --git a/exercises/client-env.sh b/exercises/client-env.sh
index 4a0609a..1d2f4f5 100755
--- a/exercises/client-env.sh
+++ b/exercises/client-env.sh
@@ -41,7 +41,6 @@
 unset NOVA_REGION_NAME
 unset NOVA_URL
 unset NOVA_USERNAME
-unset NOVA_VERSION
 
 for i in OS_TENANT_NAME OS_USERNAME OS_PASSWORD OS_AUTH_URL; do
     is_set $i
@@ -101,9 +100,6 @@
             STATUS_EC2="Failed"
             RETURN=1
         fi
-
-        # Clean up side effects
-        unset NOVA_VERSION
     fi
 fi
 
diff --git a/exercises/neutron-adv-test.sh b/exercises/neutron-adv-test.sh
index a8fbd86..9bcb766 100755
--- a/exercises/neutron-adv-test.sh
+++ b/exercises/neutron-adv-test.sh
@@ -235,7 +235,7 @@
     local NET_ID
     NET_ID=$(neutron net-create --tenant-id $TENANT_ID $NET_NAME $EXTRA| grep ' id ' | awk '{print $4}' )
     die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $TENANT_ID $NET_NAME $EXTRA"
-    neutron subnet-create --ip-version 4 --tenant-id $TENANT_ID --gateway $GATEWAY $NET_ID $CIDR
+    neutron subnet-create --ip-version 4 --tenant-id $TENANT_ID --gateway $GATEWAY --subnetpool None $NET_ID $CIDR
     neutron_debug_admin probe-create --device-owner compute $NET_ID
     source $TOP_DIR/openrc demo demo
 }
diff --git a/exercises/swift.sh b/exercises/swift.sh
index afcede8..4a41e0f 100755
--- a/exercises/swift.sh
+++ b/exercises/swift.sh
@@ -2,7 +2,7 @@
 
 # **swift.sh**
 
-# Test swift via the ``swift`` command line from ``python-swiftclient``
+# Test swift via the ``python-openstackclient`` command line
 
 echo "*********************************************************************"
 echo "Begin DevStack Exercise: $0"
@@ -39,26 +39,29 @@
 
 # Container name
 CONTAINER=ex-swift
+OBJECT=/etc/issue
 
 
 # Testing Swift
 # =============
 
 # Check if we have to swift via keystone
-swift stat || die $LINENO "Failure getting status"
+openstack object store account show || die $LINENO "Failure getting account status"
 
 # We start by creating a test container
 openstack container create $CONTAINER || die $LINENO "Failure creating container $CONTAINER"
 
-# add some files into it.
-openstack object create $CONTAINER /etc/issue || die $LINENO "Failure uploading file to container $CONTAINER"
+# add a file into it.
+openstack object create $CONTAINER $OBJECT || die $LINENO "Failure uploading file to container $CONTAINER"
 
-# list them
+# list the objects
 openstack object list $CONTAINER || die $LINENO "Failure listing contents of container $CONTAINER"
 
-# And we may want to delete them now that we have tested that
-# everything works.
-swift delete $CONTAINER || die $LINENO "Failure deleting container $CONTAINER"
+# delete the object first
+openstack object delete $CONTAINER $OBJECT || die $LINENO "Failure deleting object $OBJECT in container $CONTAINER"
+
+# delete the container
+openstack container delete $CONTAINER || die $LINENO "Failure deleting container $CONTAINER"
 
 set +o xtrace
 echo "*********************************************************************"
diff --git a/extras.d/50-ironic.sh b/extras.d/50-ironic.sh
index 3b8e3d5..0ee6a94 100644
--- a/extras.d/50-ironic.sh
+++ b/extras.d/50-ironic.sh
@@ -1,5 +1,12 @@
 # ironic.sh - Devstack extras script to install ironic
 
+# NOTE(jroll) this is used for the transition to a devstack plugin in
+# the ironic tree.
+IRONIC_USING_PLUGIN=$(trueorfalse False IRONIC_USING_PLUGIN)
+if [[ "$IRONIC_USING_PLUGIN" == "True" ]] ; then
+    return 0
+fi
+
 if is_service_enabled ir-api ir-cond; then
     if [[ "$1" == "source" ]]; then
         # Initial source
diff --git a/extras.d/README.md b/extras.d/README.md
index 7c2e4fe..4cec14b 100644
--- a/extras.d/README.md
+++ b/extras.d/README.md
@@ -14,10 +14,13 @@
 entire `stack.sh` variable space is available.  The scripts are
 sourced with one or more arguments, the first of which defines the hook phase:
 
-    source | stack | unstack | clean
+    override_defaults | source | stack | unstack | clean
 
-    source: always called first in any of the scripts, used to set the
-        initial defaults in a lib/* script or similar
+    override_defaults: always called first in any of the scripts, used to
+        override defaults (if need be) that are otherwise set in lib/* scripts
+
+    source: called by stack.sh. Used to set the initial defaults in a lib/*
+        script or similar
 
     stack: called by stack.sh.  There are four possible values for
         the second arg to distinguish the phase stack.sh is in:
diff --git a/files/apache-heat-api-cfn.template b/files/apache-heat-api-cfn.template
new file mode 100644
index 0000000..ab33c66
--- /dev/null
+++ b/files/apache-heat-api-cfn.template
@@ -0,0 +1,27 @@
+Listen %PUBLICPORT%
+
+<VirtualHost *:%PUBLICPORT%>
+    WSGIDaemonProcess heat-api-cfn processes=2 threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
+    WSGIProcessGroup heat-api-cfn
+    WSGIScriptAlias / %HEAT_BIN_DIR%/heat-wsgi-api-cfn
+    WSGIApplicationGroup %{GLOBAL}
+    WSGIPassAuthorization On
+    AllowEncodedSlashes On
+    <IfVersion >= 2.4>
+      ErrorLogFormat "%{cu}t %M"
+    </IfVersion>
+    ErrorLog /var/log/%APACHE_NAME%/heat-api-cfn.log
+    %SSLENGINE%
+    %SSLCERTFILE%
+    %SSLKEYFILE%
+
+    <Directory %HEAT_BIN_DIR%>
+        <IfVersion >= 2.4>
+            Require all granted
+        </IfVersion>
+        <IfVersion < 2.4>
+            Order allow,deny
+            Allow from all
+        </IfVersion>
+    </Directory>
+</VirtualHost>
diff --git a/files/apache-heat-api-cloudwatch.template b/files/apache-heat-api-cloudwatch.template
new file mode 100644
index 0000000..06c91bb
--- /dev/null
+++ b/files/apache-heat-api-cloudwatch.template
@@ -0,0 +1,27 @@
+Listen %PUBLICPORT%
+
+<VirtualHost *:%PUBLICPORT%>
+    WSGIDaemonProcess heat-api-cloudwatch processes=2 threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
+    WSGIProcessGroup heat-api-cloudwatch
+    WSGIScriptAlias / %HEAT_BIN_DIR%/heat-wsgi-api-cloudwatch
+    WSGIApplicationGroup %{GLOBAL}
+    WSGIPassAuthorization On
+    AllowEncodedSlashes On
+    <IfVersion >= 2.4>
+      ErrorLogFormat "%{cu}t %M"
+    </IfVersion>
+    ErrorLog /var/log/%APACHE_NAME%/heat-api-cloudwatch.log
+    %SSLENGINE%
+    %SSLCERTFILE%
+    %SSLKEYFILE%
+
+    <Directory %HEAT_BIN_DIR%>
+        <IfVersion >= 2.4>
+            Require all granted
+        </IfVersion>
+        <IfVersion < 2.4>
+            Order allow,deny
+            Allow from all
+        </IfVersion>
+    </Directory>
+</VirtualHost>
diff --git a/files/apache-heat-api.template b/files/apache-heat-api.template
new file mode 100644
index 0000000..4924b39
--- /dev/null
+++ b/files/apache-heat-api.template
@@ -0,0 +1,27 @@
+Listen %PUBLICPORT%
+
+<VirtualHost *:%PUBLICPORT%>
+    WSGIDaemonProcess heat-api processes=3 threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
+    WSGIProcessGroup heat-api
+    WSGIScriptAlias / %HEAT_BIN_DIR%/heat-wsgi-api
+    WSGIApplicationGroup %{GLOBAL}
+    WSGIPassAuthorization On
+    AllowEncodedSlashes On
+    <IfVersion >= 2.4>
+      ErrorLogFormat "%{cu}t %M"
+    </IfVersion>
+    ErrorLog /var/log/%APACHE_NAME%/heat-api.log
+    %SSLENGINE%
+    %SSLCERTFILE%
+    %SSLKEYFILE%
+
+    <Directory %HEAT_BIN_DIR%>
+        <IfVersion >= 2.4>
+            Require all granted
+        </IfVersion>
+        <IfVersion < 2.4>
+            Order allow,deny
+            Allow from all
+        </IfVersion>
+    </Directory>
+</VirtualHost>
diff --git a/files/apache-keystone.template b/files/apache-keystone.template
index 4d3d2d6..f9fa265 100644
--- a/files/apache-keystone.template
+++ b/files/apache-keystone.template
@@ -2,6 +2,16 @@
 Listen %ADMINPORT%
 LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\" %D(us)" keystone_combined
 
+<Directory %KEYSTONE_BIN%>
+    <IfVersion >= 2.4>
+        Require all granted
+    </IfVersion>
+    <IfVersion < 2.4>
+        Order allow,deny
+        Allow from all
+    </IfVersion>
+</Directory>
+
 <VirtualHost *:%PUBLICPORT%>
     WSGIDaemonProcess keystone-public processes=5 threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
     WSGIProcessGroup keystone-public
@@ -16,16 +26,6 @@
     %SSLENGINE%
     %SSLCERTFILE%
     %SSLKEYFILE%
-
-    <Directory %KEYSTONE_BIN%>
-        <IfVersion >= 2.4>
-            Require all granted
-        </IfVersion>
-        <IfVersion < 2.4>
-            Order allow,deny
-            Allow from all
-        </IfVersion>
-    </Directory>
 </VirtualHost>
 
 <VirtualHost *:%ADMINPORT%>
@@ -42,19 +42,9 @@
     %SSLENGINE%
     %SSLCERTFILE%
     %SSLKEYFILE%
-
-    <Directory %KEYSTONE_BIN%>
-        <IfVersion >= 2.4>
-            Require all granted
-        </IfVersion>
-        <IfVersion < 2.4>
-            Order allow,deny
-            Allow from all
-        </IfVersion>
-    </Directory>
 </VirtualHost>
 
-Alias /identity %PUBLICWSGI%
+Alias /identity %KEYSTONE_BIN%/keystone-wsgi-public
 <Location /identity>
     SetHandler wsgi-script
     Options +ExecCGI
@@ -64,7 +54,7 @@
     WSGIPassAuthorization On
 </Location>
 
-Alias /identity_admin %ADMINWSGI%
+Alias /identity_admin %KEYSTONE_BIN%/keystone-wsgi-admin
 <Location /identity_admin>
     SetHandler wsgi-script
     Options +ExecCGI
diff --git a/files/apache-nova-api.template b/files/apache-nova-api.template
index 4908152..bcf406e 100644
--- a/files/apache-nova-api.template
+++ b/files/apache-nova-api.template
@@ -7,7 +7,7 @@
     WSGIApplicationGroup %{GLOBAL}
     WSGIPassAuthorization On
     <IfVersion >= 2.4>
-      ErrorLogFormat "%{cu}t %M"
+      ErrorLogFormat "%M"
     </IfVersion>
     ErrorLog /var/log/%APACHE_NAME%/nova-api.log
     %SSLENGINE%
diff --git a/files/apache-nova-ec2-api.template b/files/apache-nova-ec2-api.template
index 235d958..7b1d68b 100644
--- a/files/apache-nova-ec2-api.template
+++ b/files/apache-nova-ec2-api.template
@@ -7,10 +7,19 @@
     WSGIApplicationGroup %{GLOBAL}
     WSGIPassAuthorization On
     <IfVersion >= 2.4>
-      ErrorLogFormat "%{cu}t %M"
+      ErrorLogFormat "%M"
     </IfVersion>
     ErrorLog /var/log/%APACHE_NAME%/nova-ec2-api.log
     %SSLENGINE%
     %SSLCERTFILE%
     %SSLKEYFILE%
 </VirtualHost>
+
+Alias /ec2 %PUBLICWSGI%
+<Location /ec2>
+    SetHandler wsgi-script
+    Options +ExecCGI
+    WSGIProcessGroup nova-ec2-api
+    WSGIApplicationGroup %{GLOBAL}
+    WSGIPassAuthorization On
+</Location>
diff --git a/files/apache-nova-metadata.template b/files/apache-nova-metadata.template
new file mode 100644
index 0000000..6231c1c
--- /dev/null
+++ b/files/apache-nova-metadata.template
@@ -0,0 +1,25 @@
+Listen %PUBLICPORT%
+
+<VirtualHost *:%PUBLICPORT%>
+    WSGIDaemonProcess nova-metadata processes=%APIWORKERS% threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
+    WSGIProcessGroup nova-metadata
+    WSGIScriptAlias / %PUBLICWSGI%
+    WSGIApplicationGroup %{GLOBAL}
+    WSGIPassAuthorization On
+    <IfVersion >= 2.4>
+      ErrorLogFormat "%M"
+    </IfVersion>
+    ErrorLog /var/log/%APACHE_NAME%/nova-metadata.log
+    %SSLENGINE%
+    %SSLCERTFILE%
+    %SSLKEYFILE%
+</VirtualHost>
+
+Alias /metadata %PUBLICWSGI%
+<Location /metadata>
+    SetHandler wsgi-script
+    Options +ExecCGI
+    WSGIProcessGroup nova-metadata
+    WSGIApplicationGroup %{GLOBAL}
+    WSGIPassAuthorization On
+</Location>
diff --git a/files/debs/ceilometer-collector b/files/debs/ceilometer-collector
index f1b692a..d1e9eef 100644
--- a/files/debs/ceilometer-collector
+++ b/files/debs/ceilometer-collector
@@ -1,6 +1,3 @@
-python-pymongo #NOPRIME
-mongodb-server #NOPRIME
 libnspr4-dev
-pkg-config
-libxml2-dev
-libxslt-dev
\ No newline at end of file
+mongodb-server #NOPRIME
+python-pymongo #NOPRIME
diff --git a/files/debs/cinder b/files/debs/cinder
index 51908eb..3595e01 100644
--- a/files/debs/cinder
+++ b/files/debs/cinder
@@ -1,6 +1,5 @@
-tgt # NOPRIME
 lvm2
-qemu-utils
-libpq-dev
 open-iscsi
 open-iscsi-utils # Deprecated since quantal dist:precise
+qemu-utils
+tgt # NOPRIME
diff --git a/files/debs/devlibs b/files/debs/devlibs
deleted file mode 100644
index 0446ceb..0000000
--- a/files/debs/devlibs
+++ /dev/null
@@ -1,7 +0,0 @@
-libffi-dev  # pyOpenSSL
-libmysqlclient-dev  # MySQL-python
-libpq-dev  # psycopg2
-libssl-dev  # pyOpenSSL
-libxml2-dev  # lxml
-libxslt1-dev  # lxml
-python-dev  # pyOpenSSL
diff --git a/files/debs/general b/files/debs/general
index 1460526..1215147 100644
--- a/files/debs/general
+++ b/files/debs/general
@@ -1,27 +1,33 @@
+bc
 bridge-utils
-screen
-unzip
-wget
-psmisc
-gcc
+curl
 g++
+gcc
+gettext  # used for compiling message catalogs
 git
 graphviz # needed for docs
+iputils-ping
+libffi-dev # for pyOpenSSL
+libjpeg-dev # Pillow 3.0.0
+libmysqlclient-dev  # MySQL-python
+libpq-dev  # psycopg2
+libssl-dev # for pyOpenSSL
+libxml2-dev  # lxml
+libxslt1-dev  # lxml
+libyaml-dev
 lsof # useful when debugging
+openjdk-7-jre-headless  # NOPRIME
 openssh-server
 openssl
-iputils-ping
-wget
-curl
-tcpdump
-tar
-python-dev
-python2.7
-python-gdbm # needed for testr
-bc
-libyaml-dev
-libffi-dev
-libssl-dev # for pyOpenSSL
-gettext  # used for compiling message catalogs
-openjdk-7-jre-headless  # NOPRIME
 pkg-config
+psmisc
+python2.7
+python-dev
+python-gdbm # needed for testr
+screen
+tar
+tcpdump
+unzip
+wget
+wget
+zlib1g-dev
diff --git a/files/debs/glance b/files/debs/glance
deleted file mode 100644
index 37877a8..0000000
--- a/files/debs/glance
+++ /dev/null
@@ -1,6 +0,0 @@
-libmysqlclient-dev
-libpq-dev
-libssl-dev
-libxml2-dev
-libxslt1-dev
-zlib1g-dev
diff --git a/files/debs/ironic b/files/debs/ironic
index 0a906db..4d5a6aa 100644
--- a/files/debs/ironic
+++ b/files/debs/ironic
@@ -6,8 +6,8 @@
 libvirt-bin
 open-iscsi
 openssh-client
-openvswitch-switch
 openvswitch-datapath-dkms
+openvswitch-switch
 python-libguestfs
 python-libvirt
 qemu
diff --git a/files/debs/keystone b/files/debs/keystone
index 70a5649..370e4aa 100644
--- a/files/debs/keystone
+++ b/files/debs/keystone
@@ -1,7 +1,5 @@
-python-lxml
-sqlite3
-python-mysqldb
-python-mysql.connector
+libkrb5-dev
 libldap2-dev
 libsasl2-dev
-libkrb5-dev
+python-mysqldb
+sqlite3
diff --git a/files/debs/ldap b/files/debs/ldap
index 26f7aef..aa3a934 100644
--- a/files/debs/ldap
+++ b/files/debs/ldap
@@ -1,3 +1,3 @@
 ldap-utils
-slapd
 python-ldap
+slapd
diff --git a/files/debs/n-cpu b/files/debs/n-cpu
index ffc947a..0da57ee 100644
--- a/files/debs/n-cpu
+++ b/files/debs/n-cpu
@@ -1,8 +1,8 @@
-qemu-utils
+cryptsetup
+genisoimage
 lvm2 # NOPRIME
 open-iscsi
-genisoimage
-sysfsutils
-sg3-utils
 python-guestfs # NOPRIME
-cryptsetup
+qemu-utils
+sg3-utils
+sysfsutils
diff --git a/files/debs/n-novnc b/files/debs/n-novnc
deleted file mode 100644
index c8722b9..0000000
--- a/files/debs/n-novnc
+++ /dev/null
@@ -1 +0,0 @@
-python-numpy
diff --git a/files/debs/neutron b/files/debs/neutron
index b5a457e..e53cc68 100644
--- a/files/debs/neutron
+++ b/files/debs/neutron
@@ -1,18 +1,17 @@
 acl
-ebtables
-iptables
-iputils-ping
-iputils-arping
-libmysqlclient-dev
-mysql-server #NOPRIME
-sudo
-postgresql-server-dev-all
-python-mysqldb
-python-mysql.connector
 dnsmasq-base
 dnsmasq-utils # for dhcp_release only available in dist:precise
+ebtables
+iptables
+iputils-arping
+iputils-ping
+libmysqlclient-dev
+mysql-server #NOPRIME
+postgresql-server-dev-all
+python-mysqldb
 rabbitmq-server # NOPRIME
-sqlite3
-vlan
 radvd # NOPRIME
+sqlite3
+sudo
 uuid-runtime
+vlan
diff --git a/files/debs/nova b/files/debs/nova
index 346b8b3..58dad41 100644
--- a/files/debs/nova
+++ b/files/debs/nova
@@ -1,31 +1,25 @@
+conntrack
+curl
 dnsmasq-base
 dnsmasq-utils # for dhcp_release
-conntrack
-kpartx
-parted
-iputils-arping
-libmysqlclient-dev
-mysql-server # NOPRIME
-python-mysqldb
-python-mysql.connector
-python-lxml # needed for glance which is needed for nova --- this shouldn't be here
-gawk
-iptables
 ebtables
-sqlite3
-sudo
-qemu-kvm # NOPRIME
-qemu # dist:wheezy,jessie NOPRIME
+gawk
+genisoimage # required for config_drive
+iptables
+iputils-arping
+kpartx
+libjs-jquery-tablesorter # Needed for coverage html reports
+libmysqlclient-dev
 libvirt-bin # NOPRIME
 libvirt-dev # NOPRIME
+mysql-server # NOPRIME
+parted
 pm-utils
-libjs-jquery-tablesorter # Needed for coverage html reports
-vlan
-curl
-genisoimage # required for config_drive
+python-mysqldb
+qemu # dist:wheezy,jessie NOPRIME
+qemu-kvm # NOPRIME
 rabbitmq-server # NOPRIME
 socat # used by ajaxterm
-python-libvirt # NOPRIME
-python-libxml2
-python-numpy # used by websockify for spice console
-python-m2crypto
+sqlite3
+sudo
+vlan
diff --git a/files/debs/swift b/files/debs/swift
index 726786e..4b8ac3d 100644
--- a/files/debs/swift
+++ b/files/debs/swift
@@ -1,4 +1,5 @@
 curl
+liberasurecode-dev
 make
 memcached
 sqlite3
diff --git a/files/debs/tempest b/files/debs/tempest
deleted file mode 100644
index bb09529..0000000
--- a/files/debs/tempest
+++ /dev/null
@@ -1,2 +0,0 @@
-libxml2-dev
-libxslt1-dev
diff --git a/files/debs/trove b/files/debs/trove
deleted file mode 100644
index 96f8f29..0000000
--- a/files/debs/trove
+++ /dev/null
@@ -1 +0,0 @@
-libxslt1-dev
diff --git a/files/debs/zookeeper b/files/debs/zookeeper
new file mode 100644
index 0000000..f41b559
--- /dev/null
+++ b/files/debs/zookeeper
@@ -0,0 +1 @@
+zookeeperd
diff --git a/files/ebtables.workaround b/files/ebtables.workaround
new file mode 100644
index 0000000..c8af51f
--- /dev/null
+++ b/files/ebtables.workaround
@@ -0,0 +1,23 @@
+#!/bin/bash
+#
+# Copyright 2015 Hewlett-Packard Development Company, L.P.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+#
+# This is a terrible, terrible, truly terrible work around for
+# environments that have libvirt < 1.2.11. ebtables requires that you
+# specifically tell it you would like to not race and get punched in
+# the face when 2 run at the same time with a --concurrent flag.
+
+flock -w 300 /var/lock/ebtables.nova /sbin/ebtables.real $@
diff --git a/files/rpms-suse/ceilometer-collector b/files/rpms-suse/ceilometer-collector
index 5e4dfcc..fc75ffa 100644
--- a/files/rpms-suse/ceilometer-collector
+++ b/files/rpms-suse/ceilometer-collector
@@ -1,3 +1,3 @@
-# Not available in openSUSE main repositories, but can be fetched from OBS
 # (devel:languages:python and server:database projects)
 mongodb
+# Not available in openSUSE main repositories, but can be fetched from OBS
diff --git a/files/rpms-suse/ceph b/files/rpms-suse/ceph
index 8d46500..8c4955d 100644
--- a/files/rpms-suse/ceph
+++ b/files/rpms-suse/ceph
@@ -1,3 +1,3 @@
 ceph    # NOPRIME
-xfsprogs
 lsb
+xfsprogs
diff --git a/files/rpms-suse/cinder b/files/rpms-suse/cinder
index 3fd03cc..189a232 100644
--- a/files/rpms-suse/cinder
+++ b/files/rpms-suse/cinder
@@ -1,6 +1,4 @@
 lvm2
-tgt # NOPRIME
-qemu-tools
-python-devel
-postgresql-devel
 open-iscsi
+qemu-tools
+tgt # NOPRIME
diff --git a/files/rpms-suse/devlibs b/files/rpms-suse/devlibs
deleted file mode 100644
index 54d13a3..0000000
--- a/files/rpms-suse/devlibs
+++ /dev/null
@@ -1,6 +0,0 @@
-libffi-devel  # pyOpenSSL
-libopenssl-devel  # pyOpenSSL
-libxslt-devel  # lxml
-postgresql-devel  # psycopg2
-libmysqlclient-devel # MySQL-python
-python-devel  # pyOpenSSL
diff --git a/files/rpms-suse/general b/files/rpms-suse/general
index 42756d8..34a2955 100644
--- a/files/rpms-suse/general
+++ b/files/rpms-suse/general
@@ -8,16 +8,23 @@
 git-core
 graphviz # docs
 iputils
+libffi-devel  # pyOpenSSL
+libjpeg8-devel # Pillow 3.0.0
+libmysqlclient-devel # MySQL-python
 libopenssl-devel # to rebuild pyOpenSSL if needed
+libxslt-devel  # lxml
 lsof # useful when debugging
 make
+net-tools
 openssh
 openssl
+postgresql-devel  # psycopg2
 psmisc
 python-cmd2 # dist:opensuse-12.3
+python-devel  # pyOpenSSL
 screen
 tar
 tcpdump
 unzip
 wget
-net-tools
+zlib-devel
diff --git a/files/rpms-suse/glance b/files/rpms-suse/glance
deleted file mode 100644
index bf512de..0000000
--- a/files/rpms-suse/glance
+++ /dev/null
@@ -1 +0,0 @@
-python-devel
diff --git a/files/rpms-suse/horizon b/files/rpms-suse/horizon
index 77f7c34..753ea76 100644
--- a/files/rpms-suse/horizon
+++ b/files/rpms-suse/horizon
@@ -1,2 +1,2 @@
-apache2  # NOPRIME
 apache2-mod_wsgi  # NOPRIME
+apache2  # NOPRIME
diff --git a/files/rpms-suse/keystone b/files/rpms-suse/keystone
index c838b41..46832c7 100644
--- a/files/rpms-suse/keystone
+++ b/files/rpms-suse/keystone
@@ -1,4 +1,3 @@
 cyrus-sasl-devel
 openldap2-devel
-python-devel
 sqlite3
diff --git a/files/rpms-suse/n-api b/files/rpms-suse/n-api
index 6f59e60..af5ac2f 100644
--- a/files/rpms-suse/n-api
+++ b/files/rpms-suse/n-api
@@ -1,2 +1,2 @@
-python-dateutil
 fping
+python-dateutil
diff --git a/files/rpms-suse/n-cpu b/files/rpms-suse/n-cpu
index b3a468d..29bd31b 100644
--- a/files/rpms-suse/n-cpu
+++ b/files/rpms-suse/n-cpu
@@ -1,7 +1,7 @@
-# Stuff for diablo volumes
+cryptsetup
 genisoimage
 lvm2
 open-iscsi
-sysfsutils
 sg3_utils
-cryptsetup
+# Stuff for diablo volumes
+sysfsutils
diff --git a/files/rpms-suse/neutron b/files/rpms-suse/neutron
index 1339799..e9abc6e 100644
--- a/files/rpms-suse/neutron
+++ b/files/rpms-suse/neutron
@@ -5,9 +5,8 @@
 iptables
 iputils
 mariadb # NOPRIME
-postgresql-devel
 rabbitmq-server # NOPRIME
+radvd # NOPRIME
 sqlite3
 sudo
 vlan
-radvd # NOPRIME
diff --git a/files/rpms-suse/nova b/files/rpms-suse/nova
index 039456f..ae115d2 100644
--- a/files/rpms-suse/nova
+++ b/files/rpms-suse/nova
@@ -1,7 +1,7 @@
+conntrack-tools
 curl
 dnsmasq
 dnsmasq-utils # dist:opensuse-12.3,opensuse-13.1
-conntrack-tools
 ebtables
 gawk
 genisoimage # required for config_drive
@@ -9,14 +9,13 @@
 iputils
 kpartx
 kvm # NOPRIME
-# qemu as fallback if kvm cannot be used
-qemu # NOPRIME
 libvirt # NOPRIME
 libvirt-python # NOPRIME
 mariadb # NOPRIME
 parted
 polkit
-python-devel
+# qemu as fallback if kvm cannot be used
+qemu # NOPRIME
 rabbitmq-server # NOPRIME
 socat
 sqlite3
diff --git a/files/rpms-suse/openvswitch b/files/rpms-suse/openvswitch
index edfb4d2..53f8bb2 100644
--- a/files/rpms-suse/openvswitch
+++ b/files/rpms-suse/openvswitch
@@ -1,3 +1,3 @@
+
 openvswitch
 openvswitch-switch
-
diff --git a/files/rpms-suse/swift b/files/rpms-suse/swift
index 6a824f9..3663b98 100644
--- a/files/rpms-suse/swift
+++ b/files/rpms-suse/swift
@@ -1,6 +1,6 @@
 curl
+liberasurecode-devel
 memcached
-python-devel
 sqlite3
 xfsprogs
 xinetd
diff --git a/files/rpms/ceilometer-collector b/files/rpms/ceilometer-collector
index b139ed2..a8b8118 100644
--- a/files/rpms/ceilometer-collector
+++ b/files/rpms/ceilometer-collector
@@ -1,3 +1,3 @@
-selinux-policy-targeted
-mongodb-server #NOPRIME
 mongodb # NOPRIME
+mongodb-server #NOPRIME
+selinux-policy-targeted
diff --git a/files/rpms/ceph b/files/rpms/ceph
index 5483735..64befc5 100644
--- a/files/rpms/ceph
+++ b/files/rpms/ceph
@@ -1,3 +1,3 @@
 ceph    # NOPRIME
-xfsprogs
 redhat-lsb-core
+xfsprogs
diff --git a/files/rpms/cinder b/files/rpms/cinder
index a88503b..0274642 100644
--- a/files/rpms/cinder
+++ b/files/rpms/cinder
@@ -1,5 +1,4 @@
-lvm2
-scsi-target-utils # NOPRIME
-qemu-img
-postgresql-devel
 iscsi-initiator-utils
+lvm2
+qemu-img
+scsi-target-utils # NOPRIME
diff --git a/files/rpms/devlibs b/files/rpms/devlibs
deleted file mode 100644
index 385ed3b..0000000
--- a/files/rpms/devlibs
+++ /dev/null
@@ -1,8 +0,0 @@
-libffi-devel  # pyOpenSSL
-libxml2-devel  # lxml
-libxslt-devel  # lxml
-mariadb-devel  # MySQL-python
-openssl-devel  # pyOpenSSL
-postgresql-devel  # psycopg2
-python-devel  # pyOpenSSL
-redhat-rpm-config # MySQL-python rhbz-1195207 f21
diff --git a/files/rpms/dstat b/files/rpms/dstat
index 8a8f8fe..2b643b8 100644
--- a/files/rpms/dstat
+++ b/files/rpms/dstat
@@ -1 +1 @@
-dstat
\ No newline at end of file
+dstat
diff --git a/files/rpms/general b/files/rpms/general
index c3f3de8..2804682 100644
--- a/files/rpms/general
+++ b/files/rpms/general
@@ -1,31 +1,36 @@
+bc
 bridge-utils
 curl
 dbus
 euca2ools # only for testing client
 gcc
 gcc-c++
+gettext  # used for compiling message catalogs
 git-core
 graphviz # needed only for docs
+iptables-services  # NOPRIME f21,f22,f23
+java-1.7.0-openjdk-headless  # NOPRIME rhel7
+java-1.8.0-openjdk-headless  # NOPRIME f21,f22,f23
+libffi-devel
+libjpeg-turbo-devel # Pillow 3.0.0
+libxml2-devel # lxml
+libxslt-devel # lxml
+libyaml-devel
+mariadb-devel  # MySQL-python
+net-tools
 openssh-server
 openssl
 openssl-devel # to rebuild pyOpenSSL if needed
-libffi-devel
-libxml2-devel
-libxslt-devel
 pkgconfig
+postgresql-devel  # psycopg2
 psmisc
+pyOpenSSL # version in pip uses too much memory
 python-devel
+redhat-rpm-config # MySQL-python rhbz-1195207 f21
 screen
 tar
 tcpdump
 unzip
 wget
 which
-bc
-libyaml-devel
-gettext  # used for compiling message catalogs
-net-tools
-java-1.7.0-openjdk-headless  # NOPRIME rhel7
-java-1.8.0-openjdk-headless  # NOPRIME f21,f22
-pyOpenSSL # version in pip uses too much memory
-iptables-services  # NOPRIME f21,f22
+zlib-devel
diff --git a/files/rpms/glance b/files/rpms/glance
deleted file mode 100644
index 479194f..0000000
--- a/files/rpms/glance
+++ /dev/null
@@ -1,6 +0,0 @@
-libxml2-devel
-libxslt-devel
-mysql-devel
-openssl-devel
-postgresql-devel
-zlib-devel
diff --git a/files/rpms/horizon b/files/rpms/horizon
index b2cf0de..aeb2cb5 100644
--- a/files/rpms/horizon
+++ b/files/rpms/horizon
@@ -1,5 +1,5 @@
 Django
 httpd # NOPRIME
 mod_wsgi  # NOPRIME
-pyxattr
 pcre-devel  # pyScss
+pyxattr
diff --git a/files/rpms/keystone b/files/rpms/keystone
index 8074119..c01c261 100644
--- a/files/rpms/keystone
+++ b/files/rpms/keystone
@@ -1,4 +1,3 @@
-MySQL-python
-libxslt-devel
-sqlite
 mod_ssl
+MySQL-python
+sqlite
diff --git a/files/rpms/ldap b/files/rpms/ldap
index d89c4cf..d5b8fa4 100644
--- a/files/rpms/ldap
+++ b/files/rpms/ldap
@@ -1,2 +1,2 @@
-openldap-servers
 openldap-clients
+openldap-servers
diff --git a/files/rpms/n-cpu b/files/rpms/n-cpu
index 81278b3..7773b04 100644
--- a/files/rpms/n-cpu
+++ b/files/rpms/n-cpu
@@ -1,7 +1,7 @@
-# Stuff for diablo volumes
+cryptsetup
+genisoimage
 iscsi-initiator-utils
 lvm2
-genisoimage
-sysfsutils
 sg3_utils
-cryptsetup
+# Stuff for diablo volumes
+sysfsutils
diff --git a/files/rpms/neutron b/files/rpms/neutron
index 29851be..2e49a0c 100644
--- a/files/rpms/neutron
+++ b/files/rpms/neutron
@@ -1,16 +1,14 @@
-MySQL-python
 acl
 dnsmasq # for q-dhcp
 dnsmasq-utils # for dhcp_release
 ebtables
 iptables
 iputils
-mysql-connector-python
 mysql-devel
+MySQL-python
 mysql-server # NOPRIME
 openvswitch # NOPRIME
-postgresql-devel
 rabbitmq-server # NOPRIME
+radvd # NOPRIME
 sqlite
 sudo
-radvd # NOPRIME
diff --git a/files/rpms/nova b/files/rpms/nova
index 6eeb623..4db9a06 100644
--- a/files/rpms/nova
+++ b/files/rpms/nova
@@ -1,27 +1,27 @@
-MySQL-python
+conntrack-tools
 curl
 dnsmasq # for nova-network
 dnsmasq-utils # for dhcp_release
-conntrack-tools
 ebtables
 gawk
 genisoimage # required for config_drive
 iptables
 iputils
+kernel-modules # dist:f21,f22,f23
 kpartx
 kvm # NOPRIME
-qemu-kvm # NOPRIME
 libvirt-bin # NOPRIME
 libvirt-devel # NOPRIME
 libvirt-python # NOPRIME
 libxml2-python
-numpy # needed by websockify for spice console
 m2crypto
-mysql-connector-python
 mysql-devel
+MySQL-python
 mysql-server # NOPRIME
+numpy # needed by websockify for spice console
 parted
 polkit
+qemu-kvm # NOPRIME
 rabbitmq-server # NOPRIME
 sqlite
 sudo
diff --git a/files/rpms/swift b/files/rpms/swift
index 1bf57cc..46dc59d 100644
--- a/files/rpms/swift
+++ b/files/rpms/swift
@@ -1,7 +1,8 @@
 curl
+liberasurecode-devel
 memcached
 pyxattr
+rsync-daemon # dist:f22,f23
 sqlite
 xfsprogs
 xinetd
-rsync-daemon # dist:f22,f23
diff --git a/files/rpms/tempest b/files/rpms/tempest
deleted file mode 100644
index e7bbd43..0000000
--- a/files/rpms/tempest
+++ /dev/null
@@ -1 +0,0 @@
-libxslt-devel
diff --git a/files/rpms/trove b/files/rpms/trove
deleted file mode 100644
index e7bbd43..0000000
--- a/files/rpms/trove
+++ /dev/null
@@ -1 +0,0 @@
-libxslt-devel
diff --git a/files/rpms/zookeeper b/files/rpms/zookeeper
new file mode 100644
index 0000000..1bfac53
--- /dev/null
+++ b/files/rpms/zookeeper
@@ -0,0 +1 @@
+zookeeper
diff --git a/files/venv-requirements.txt b/files/venv-requirements.txt
deleted file mode 100644
index b9a55b4..0000000
--- a/files/venv-requirements.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-# Once we can prebuild wheels before a devstack run, uncomment the skipped libraries
-cryptography
-# lxml # still install from from packages
-# netifaces # still install from packages
-#numpy    # slowest wheel by far, stop building until we are actually using the output
-posix-ipc
-# psycopg # still install from packages
-pycrypto
-pyOpenSSL
-PyYAML
-xattr
diff --git a/files/zookeeper/environment b/files/zookeeper/environment
new file mode 100644
index 0000000..afa2d2f
--- /dev/null
+++ b/files/zookeeper/environment
@@ -0,0 +1,36 @@
+#
+# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# Modified from http://packages.ubuntu.com/saucy/zookeeperd
+NAME=zookeeper
+ZOOCFGDIR=/etc/zookeeper/conf
+
+# seems, that log4j requires the log4j.properties file to be in the classpath
+CLASSPATH="$ZOOCFGDIR:/usr/share/java/jline.jar:/usr/share/java/log4j-1.2.jar:/usr/share/java/xercesImpl.jar:/usr/share/java/xmlParserAPIs.jar:/usr/share/java/netty.jar:/usr/share/java/slf4j-api.jar:/usr/share/java/slf4j-log4j12.jar:/usr/share/java/zookeeper.jar"
+
+ZOOCFG="$ZOOCFGDIR/zoo.cfg"
+ZOO_LOG_DIR=/var/log/zookeeper
+USER=$NAME
+GROUP=$NAME
+PIDDIR=/var/run/$NAME
+PIDFILE=$PIDDIR/$NAME.pid
+SCRIPTNAME=/etc/init.d/$NAME
+JAVA=/usr/bin/java
+ZOOMAIN="org.apache.zookeeper.server.quorum.QuorumPeerMain"
+ZOO_LOG4J_PROP="INFO,ROLLINGFILE"
+JMXLOCALONLY=false
+JAVA_OPTS=""
diff --git a/files/zookeeper/log4j.properties b/files/zookeeper/log4j.properties
new file mode 100644
index 0000000..6c45a4a
--- /dev/null
+++ b/files/zookeeper/log4j.properties
@@ -0,0 +1,69 @@
+#
+# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# From http://packages.ubuntu.com/saucy/zookeeperd
+
+# ZooKeeper Logging Configuration
+#
+
+# Format is "<default threshold> (, <appender>)+
+
+log4j.rootLogger=${zookeeper.root.logger}
+
+# Example: console appender only
+# log4j.rootLogger=INFO, CONSOLE
+
+# Example with rolling log file
+#log4j.rootLogger=DEBUG, CONSOLE, ROLLINGFILE
+
+# Example with rolling log file and tracing
+#log4j.rootLogger=TRACE, CONSOLE, ROLLINGFILE, TRACEFILE
+
+#
+# Log INFO level and above messages to the console
+#
+log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
+log4j.appender.CONSOLE.Threshold=INFO
+log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
+log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n
+
+#
+# Add ROLLINGFILE to rootLogger to get log file output
+#    Log DEBUG level and above messages to a log file
+log4j.appender.ROLLINGFILE=org.apache.log4j.RollingFileAppender
+log4j.appender.ROLLINGFILE.Threshold=WARN
+log4j.appender.ROLLINGFILE.File=${zookeeper.log.dir}/zookeeper.log
+
+# Max log file size of 10MB
+log4j.appender.ROLLINGFILE.MaxFileSize=10MB
+# uncomment the next line to limit number of backup files
+#log4j.appender.ROLLINGFILE.MaxBackupIndex=10
+
+log4j.appender.ROLLINGFILE.layout=org.apache.log4j.PatternLayout
+log4j.appender.ROLLINGFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L] - %m%n
+
+
+#
+# Add TRACEFILE to rootLogger to get log file output
+#    Log DEBUG level and above messages to a log file
+log4j.appender.TRACEFILE=org.apache.log4j.FileAppender
+log4j.appender.TRACEFILE.Threshold=TRACE
+log4j.appender.TRACEFILE.File=${zookeeper.log.dir}/zookeeper_trace.log
+
+log4j.appender.TRACEFILE.layout=org.apache.log4j.PatternLayout
+### Notice we are including log4j's NDC here (%x)
+log4j.appender.TRACEFILE.layout.ConversionPattern=%d{ISO8601} - %-5p [%t:%C{1}@%L][%x] - %m%n
diff --git a/files/zookeeper/myid b/files/zookeeper/myid
new file mode 100644
index 0000000..c227083
--- /dev/null
+++ b/files/zookeeper/myid
@@ -0,0 +1 @@
+0
\ No newline at end of file
diff --git a/files/zookeeper/zoo.cfg b/files/zookeeper/zoo.cfg
new file mode 100644
index 0000000..b8f5582
--- /dev/null
+++ b/files/zookeeper/zoo.cfg
@@ -0,0 +1,74 @@
+#
+# (C) Copyright 2015 Hewlett Packard Enterprise Development Company LP
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# http://hadoop.apache.org/zookeeper/docs/current/zookeeperAdmin.html
+
+# The number of milliseconds of each tick
+tickTime=2000
+# The number of ticks that the initial
+# synchronization phase can take
+initLimit=10
+# The number of ticks that can pass between
+# sending a request and getting an acknowledgement
+syncLimit=5
+# the directory where the snapshot is stored.
+dataDir=/var/lib/zookeeper
+# Place the dataLogDir to a separate physical disc for better performance
+# dataLogDir=/disk2/zookeeper
+
+# the port at which the clients will connect
+clientPort=2181
+
+# Maximum number of clients that can connect from one client
+maxClientCnxns=60
+
+# specify all zookeeper servers
+# The fist port is used by followers to connect to the leader
+# The second one is used for leader election
+
+server.0=127.0.0.1:2888:3888
+
+# To avoid seeks ZooKeeper allocates space in the transaction log file in
+# blocks of preAllocSize kilobytes. The default block size is 64M. One reason
+# for changing the size of the blocks is to reduce the block size if snapshots
+# are taken more often. (Also, see snapCount).
+#preAllocSize=65536
+
+# Clients can submit requests faster than ZooKeeper can process them,
+# especially if there are a lot of clients. To prevent ZooKeeper from running
+# out of memory due to queued requests, ZooKeeper will throttle clients so that
+# there is no more than globalOutstandingLimit outstanding requests in the
+# system. The default limit is 1,000.ZooKeeper logs transactions to a
+# transaction log. After snapCount transactions are written to a log file a
+# snapshot is started and a new transaction log file is started. The default
+# snapCount is 10,000.
+#snapCount=1000
+
+# If this option is defined, requests will be will logged to a trace file named
+# traceFile.year.month.day.
+#traceFile=
+
+# Leader accepts client connections. Default value is "yes". The leader machine
+# coordinates updates. For higher update throughput at thes slight expense of
+# read throughput the leader can be configured to not accept clients and focus
+# on coordination.
+#leaderServes=yes
+
+# Autopurge every hour to avoid using lots of disk in bursts
+# Order of the next 2 properties matters.
+# autopurge.snapRetainCount must be before autopurge.purgeInterval.
+autopurge.snapRetainCount=3
+autopurge.purgeInterval=1
\ No newline at end of file
diff --git a/functions b/functions
index ca5955e..762fc47 100644
--- a/functions
+++ b/functions
@@ -22,7 +22,7 @@
 source ${FUNC_DIR}/inc/rootwrap
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_FUNCTIONS=$(set +o | grep xtrace)
 set +o xtrace
 
 # Check if a function already exists
@@ -410,7 +410,7 @@
     ip=$(echo "$nova_result" | grep "$network_name" | get_field 2)
     if [[ $ip = "" ]];then
         echo "$nova_result"
-        die $LINENO "[Fail] Coudn't get ipaddress of VM"
+        die $LINENO "[Fail] Couldn't get ipaddress of VM"
     fi
     echo $ip
 }
@@ -603,7 +603,7 @@
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_FUNCTIONS
 
 # Local variables:
 # mode: shell-script
diff --git a/functions-common b/functions-common
index 42555a9..1b01eef 100644
--- a/functions-common
+++ b/functions-common
@@ -32,7 +32,7 @@
 #
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_FUNCTIONS_COMMON=$(set +o | grep xtrace)
 set +o xtrace
 
 # ensure we don't re-source this in the same environment
@@ -76,37 +76,36 @@
     # The location is a variable to allow for easier refactoring later to make it
     # overridable. There is currently no usecase where doing so makes sense, so
     # it's not currently configurable.
-    for clouds_path in /etc/openstack ~/.config/openstack ; do
-        CLOUDS_YAML=$clouds_path/clouds.yaml
 
-        sudo mkdir -p $(dirname $CLOUDS_YAML)
-        sudo chown -R $STACK_USER $(dirname $CLOUDS_YAML)
+    CLOUDS_YAML=/etc/openstack/clouds.yaml
 
-        CA_CERT_ARG=''
-        if [ -f "$SSL_BUNDLE_FILE" ]; then
-            CA_CERT_ARG="--os-cacert $SSL_BUNDLE_FILE"
-        fi
-        $TOP_DIR/tools/update_clouds_yaml.py \
-            --file $CLOUDS_YAML \
-            --os-cloud devstack \
-            --os-region-name $REGION_NAME \
-            --os-identity-api-version 3 \
-            $CA_CERT_ARG \
-            --os-auth-url $KEYSTONE_AUTH_URI \
-            --os-username demo \
-            --os-password $ADMIN_PASSWORD \
-            --os-project-name demo
-        $TOP_DIR/tools/update_clouds_yaml.py \
-            --file $CLOUDS_YAML \
-            --os-cloud devstack-admin \
-            --os-region-name $REGION_NAME \
-            --os-identity-api-version 3 \
-            $CA_CERT_ARG \
-            --os-auth-url $KEYSTONE_AUTH_URI \
-            --os-username admin \
-            --os-password $ADMIN_PASSWORD \
-            --os-project-name admin
-    done
+    sudo mkdir -p $(dirname $CLOUDS_YAML)
+    sudo chown -R $STACK_USER /etc/openstack
+
+    CA_CERT_ARG=''
+    if [ -f "$SSL_BUNDLE_FILE" ]; then
+        CA_CERT_ARG="--os-cacert $SSL_BUNDLE_FILE"
+    fi
+    $TOP_DIR/tools/update_clouds_yaml.py \
+        --file $CLOUDS_YAML \
+        --os-cloud devstack \
+        --os-region-name $REGION_NAME \
+        --os-identity-api-version 3 \
+        $CA_CERT_ARG \
+        --os-auth-url $KEYSTONE_AUTH_URI \
+        --os-username demo \
+        --os-password $ADMIN_PASSWORD \
+        --os-project-name demo
+    $TOP_DIR/tools/update_clouds_yaml.py \
+        --file $CLOUDS_YAML \
+        --os-cloud devstack-admin \
+        --os-region-name $REGION_NAME \
+        --os-identity-api-version 3 \
+        $CA_CERT_ARG \
+        --os-auth-url $KEYSTONE_AUTH_URI \
+        --os-username admin \
+        --os-password $ADMIN_PASSWORD \
+        --os-project-name admin
 }
 
 # trueorfalse <True|False> <VAR>
@@ -911,16 +910,11 @@
 # Usage: _get_or_create_endpoint_with_interface <service> <interface> <url> <region>
 function _get_or_create_endpoint_with_interface {
     local endpoint_id
-    # TODO(dgonzalez): The check of the region name, as done in the grep
-    # statement below, exists only because keystone does currently
-    # not allow filtering the region name when listing endpoints. If keystone
-    # gets support for this, the check for the region name can be removed.
-    # Related bug in keystone: https://bugs.launchpad.net/keystone/+bug/1482772
     endpoint_id=$(openstack endpoint list \
         --service $1 \
         --interface $2 \
         --region $4 \
-        -c ID -c Region -f value | grep $4 | cut -f 1 -d " ")
+        -c ID -f value)
     if [[ -z "$endpoint_id" ]]; then
         # Creates new endpoint
         endpoint_id=$(openstack endpoint create \
@@ -984,6 +978,34 @@
     echo "$pkg_dir"
 }
 
+# Wrapper for ``apt-get update`` to try multiple times on the update
+# to address bad package mirrors (which happen all the time).
+function apt_get_update {
+    # only do this once per run
+    if [[ "$REPOS_UPDATED" == "True" && "$RETRY_UPDATE" != "True" ]]; then
+        return
+    fi
+
+    # bail if we are offline
+    [[ "$OFFLINE" = "True" ]] && return
+
+    local sudo="sudo"
+    [[ "$(id -u)" = "0" ]] && sudo="env"
+
+    # time all the apt operations
+    time_start "apt-get-update"
+
+    local proxies="http_proxy=${http_proxy:-} https_proxy=${https_proxy:-} no_proxy=${no_proxy:-} "
+    local update_cmd="$sudo $proxies apt-get update"
+    if ! timeout 300 sh -c "while ! $update_cmd; do sleep 30; done"; then
+        die $LINENO "Failed to update apt repos, we're dead now"
+    fi
+
+    REPOS_UPDATED=True
+    # stop the clock
+    time_stop "apt-get-update"
+}
+
 # Wrapper for ``apt-get`` to set cache and proxy environment variables
 # Uses globals ``OFFLINE``, ``*_proxy``
 # apt_get operation package [package ...]
@@ -1037,7 +1059,7 @@
                 # We are using BASH regexp matching feature.
                 package=${BASH_REMATCH[1]}
                 distros=${BASH_REMATCH[2]}
-                # In bash ${VAR,,} will lowecase VAR
+                # In bash ${VAR,,} will lowercase VAR
                 # Look for a match in the distro list
                 if [[ ! ${distros,,} =~ ${DISTRO,,} ]]; then
                     # If no match then skip this package
@@ -1073,6 +1095,10 @@
     local file_to_parse=""
     local service=""
 
+    if [ $# -ne 1 ]; then
+        die $LINENO "get_packages takes a single, comma-separated argument"
+    fi
+
     if [[ -z "$package_dir" ]]; then
         echo "No package directory supplied"
         return 1
@@ -1160,16 +1186,7 @@
     fi
 
     if is_ubuntu; then
-        local xtrace
-    xtrace=$(set +o | grep xtrace)
-        set +o xtrace
-        if [[ "$REPOS_UPDATED" != "True" || "$RETRY_UPDATE" = "True" ]]; then
-            # if there are transient errors pulling the updates, that's fine.
-            # It may be secondary repositories that we don't really care about.
-            apt_get update  || /bin/true
-            REPOS_UPDATED=True
-        fi
-        $xtrace
+        apt_get_update
     fi
 }
 
@@ -1349,6 +1366,7 @@
 # If the command includes shell metachatacters (;<>*) it must be run using a shell
 # If an optional group is provided sg will be used to run the
 # command as that group.
+# Uses globals ``USE_SCREEN``
 # run_process service "command-line" [group]
 function run_process {
     local service=$1
@@ -1367,7 +1385,7 @@
 
 # Helper to launch a process in a named screen
 # Uses globals ``CURRENT_LOG_TIME``, ```LOGDIR``, ``SCREEN_LOGDIR``, `SCREEN_NAME``,
-# ``SERVICE_DIR``, ``USE_SCREEN``
+# ``SERVICE_DIR``, ``SCREEN_IS_LOGGING``
 # screen_process name "command-line" [group]
 # Run a command in a shell in a screen window, if an optional group
 # is provided, use sg to set the group of the command.
@@ -1378,7 +1396,6 @@
 
     SCREEN_NAME=${SCREEN_NAME:-stack}
     SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
-    USE_SCREEN=$(trueorfalse True USE_SCREEN)
 
     screen -S $SCREEN_NAME -X screen -t $name
 
@@ -1387,8 +1404,12 @@
     echo "SCREEN_LOGDIR: $SCREEN_LOGDIR"
     echo "log: $real_logfile"
     if [[ -n ${LOGDIR} ]]; then
-        screen -S $SCREEN_NAME -p $name -X logfile "$real_logfile"
-        screen -S $SCREEN_NAME -p $name -X log on
+        if [[ "$SCREEN_IS_LOGGING" == "True" ]]; then
+            screen -S $SCREEN_NAME -p $name -X logfile "$real_logfile"
+            screen -S $SCREEN_NAME -p $name -X log on
+        fi
+        # If logging isn't active then avoid a broken symlink
+        touch "$real_logfile"
         ln -sf "$real_logfile" ${LOGDIR}/${name}.log
         if [[ -n ${SCREEN_LOGDIR} ]]; then
             # Drop the backward-compat symlink
@@ -1427,7 +1448,7 @@
 }
 
 # Screen rc file builder
-# Uses globals ``SCREEN_NAME``, ``SCREENRC``
+# Uses globals ``SCREEN_NAME``, ``SCREENRC``, ``SCREEN_IS_LOGGING``
 # screen_rc service "command-line"
 function screen_rc {
     SCREEN_NAME=${SCREEN_NAME:-stack}
@@ -1447,7 +1468,7 @@
         echo "screen -t $1 bash" >> $SCREENRC
         echo "stuff \"$2$NL\"" >> $SCREENRC
 
-        if [[ -n ${LOGDIR} ]]; then
+        if [[ -n ${LOGDIR} ]] && [[ "$SCREEN_IS_LOGGING" == "True" ]]; then
             echo "logfile ${LOGDIR}/${1}.log.${CURRENT_LOG_TIME}" >>$SCREENRC
             echo "log on" >>$SCREENRC
         fi
@@ -1458,14 +1479,13 @@
 # If a PID is available use it, kill the whole process group via TERM
 # If screen is being used kill the screen window; this will catch processes
 # that did not leave a PID behind
-# Uses globals ``SCREEN_NAME``, ``SERVICE_DIR``, ``USE_SCREEN``
+# Uses globals ``SCREEN_NAME``, ``SERVICE_DIR``
 # screen_stop_service service
 function screen_stop_service {
     local service=$1
 
     SCREEN_NAME=${SCREEN_NAME:-stack}
     SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
-    USE_SCREEN=$(trueorfalse True USE_SCREEN)
 
     if is_service_enabled $service; then
         # Clean up the screen window
@@ -1483,7 +1503,6 @@
     local service=$1
 
     SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
-    USE_SCREEN=$(trueorfalse True USE_SCREEN)
 
     if is_service_enabled $service; then
         # Kill via pid if we have one available
@@ -1502,7 +1521,7 @@
                 # this fixed in all services:
                 # https://bugs.launchpad.net/oslo-incubator/+bug/1446583
                 sleep 1
-                # /bin/true becakse pkill on a non existant process returns an error
+                # /bin/true because pkill on a non existent process returns an error
                 pkill -g $(cat $SERVICE_DIR/$SCREEN_NAME/$service.pid) || /bin/true
             fi
             rm $SERVICE_DIR/$SCREEN_NAME/$service.pid
@@ -1545,11 +1564,11 @@
 }
 
 # Tail a log file in a screen if USE_SCREEN is true.
+# Uses globals ``USE_SCREEN``
 function tail_log {
     local name=$1
     local logfile=$2
 
-    USE_SCREEN=$(trueorfalse True USE_SCREEN)
     if [[ "$USE_SCREEN" = "True" ]]; then
         screen_process "$name" "sudo tail -f $logfile"
     fi
@@ -1710,7 +1729,7 @@
         if [[ -f $dir/devstack/override-defaults ]]; then
             # be really verbose that an override is happening, as it
             # may not be obvious if things fail later.
-            echo "$plugin has overriden the following defaults"
+            echo "$plugin has overridden the following defaults"
             cat $dir/devstack/override-defaults
             source $dir/devstack/override-defaults
         fi
@@ -1741,16 +1760,18 @@
     if [[ -d $TOP_DIR/extras.d ]]; then
         local extra_plugin_file_name
         for extra_plugin_file_name in $TOP_DIR/extras.d/*.sh; do
-            [[ -r $extra_plugin_file_name ]] && source $extra_plugin_file_name $mode $phase
-            # NOTE(sdague): generate a big warning about using
-            # extras.d in an unsupported way which will let us track
-            # unsupported usage in the gate.
+            # NOTE(sdague): only process extras.d for the 3 explicitly
+            # white listed elements in tree. We want these to move out
+            # over time as well, but they are in tree, so we need to
+            # manage that.
             local exceptions="50-ironic.sh 60-ceph.sh 80-tempest.sh"
-            local extra=$(basename $extra_plugin_file_name)
+            local extra
+            extra=$(basename $extra_plugin_file_name)
             if [[ ! ( $exceptions =~ "$extra" ) ]]; then
-                deprecated "extras.d support is being removed in Mitaka-1"
-                deprecated "jobs for project $extra will break after that point"
-                deprecated "please move project to a supported devstack plugin model"
+                warn "use of extras.d is no longer supported"
+                warn "processing of project $extra is skipped"
+            else
+                [[ -r $extra_plugin_file_name ]] && source $extra_plugin_file_name $mode $phase
             fi
         done
     fi
@@ -1772,11 +1793,17 @@
 # remove extra commas from the input string (i.e. ``ENABLED_SERVICES``)
 # _cleanup_service_list service-list
 function _cleanup_service_list {
+    local xtrace
+    xtrace=$(set +o | grep xtrace)
+    set +o xtrace
+
     echo "$1" | sed -e '
         s/,,/,/g;
         s/^,//;
         s/,$//
     '
+
+    $xtrace
 }
 
 # disable_all_services() removes all current services
@@ -1794,6 +1821,10 @@
 # Uses global ``ENABLED_SERVICES``
 # disable_negated_services
 function disable_negated_services {
+    local xtrace
+    xtrace=$(set +o | grep xtrace)
+    set +o xtrace
+
     local to_remove=""
     local remaining=""
     local service
@@ -1811,6 +1842,8 @@
     # go through the service list.  if this service appears in the "to
     # be removed" list, drop it
     ENABLED_SERVICES=$(remove_disabled_services "$remaining" "$to_remove")
+
+    $xtrace
 }
 
 # disable_service() prepares the services passed as argument to be
@@ -1822,6 +1855,10 @@
 # Uses global ``DISABLED_SERVICES``
 # disable_service service [service ...]
 function disable_service {
+    local xtrace
+    xtrace=$(set +o | grep xtrace)
+    set +o xtrace
+
     local disabled_svcs="${DISABLED_SERVICES}"
     local enabled_svcs=",${ENABLED_SERVICES},"
     local service
@@ -1833,6 +1870,8 @@
     done
     DISABLED_SERVICES=$(_cleanup_service_list "$disabled_svcs")
     ENABLED_SERVICES=$(_cleanup_service_list "$enabled_svcs")
+
+    $xtrace
 }
 
 # enable_service() adds the services passed as argument to the
@@ -1846,6 +1885,10 @@
 # Uses global ``ENABLED_SERVICES``
 # enable_service service [service ...]
 function enable_service {
+    local xtrace
+    xtrace=$(set +o | grep xtrace)
+    set +o xtrace
+
     local tmpsvcs="${ENABLED_SERVICES}"
     local service
     for service in $@; do
@@ -1859,6 +1902,8 @@
     done
     ENABLED_SERVICES=$(_cleanup_service_list "$tmpsvcs")
     disable_negated_services
+
+    $xtrace
 }
 
 # is_service_enabled() checks if the service(s) specified as arguments are
@@ -1887,6 +1932,7 @@
     local xtrace
     xtrace=$(set +o | grep xtrace)
     set +o xtrace
+
     local enabled=1
     local services=$@
     local service
@@ -1912,6 +1958,7 @@
         [[ ${service} == "swift" && ${ENABLED_SERVICES} =~ "s-" ]] && enabled=0
         [[ ${service} == s-* && ${ENABLED_SERVICES} =~ "swift" ]] && enabled=0
     done
+
     $xtrace
     return $enabled
 }
@@ -1919,6 +1966,10 @@
 # remove specified list from the input string
 # remove_disabled_services service-list remove-list
 function remove_disabled_services {
+    local xtrace
+    xtrace=$(set +o | grep xtrace)
+    set +o xtrace
+
     local service_list=$1
     local remove_list=$2
     local service
@@ -1937,6 +1988,9 @@
             enabled="${enabled},$service"
         fi
     done
+
+    $xtrace
+
     _cleanup_service_list "$enabled"
 }
 
@@ -2184,14 +2238,21 @@
 # global counter for that name. Errors if that clock had not
 # previously been started.
 function time_stop {
-    local name=$1
-    local start_time=${START_TIME[$name]}
+    local name
+    local end_time
+    local elpased_time
+    local total
+    local start_time
+
+    name=$1
+    start_time=${START_TIME[$name]}
+
     if [[ -z "$start_time" ]]; then
         die $LINENO "Trying to stop the clock on $name, but it was never started"
     fi
-    local end_time=$(date +%s)
-    local elapsed_time=$(($end_time - $start_time))
-    local total=${TOTAL_TIME[$name]:-0}
+    end_time=$(date +%s)
+    elapsed_time=$(($end_time - $start_time))
+    total=${TOTAL_TIME[$name]:-0}
     # reset the clock so we can start it in the future
     START_TIME[$name]=""
     TOTAL_TIME[$name]=$(($total + $elapsed_time))
@@ -2213,7 +2274,7 @@
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_FUNCTIONS_COMMON
 
 # Local variables:
 # mode: shell-script
diff --git a/inc/ini-config b/inc/ini-config
index 42a66c6..d2830d7 100644
--- a/inc/ini-config
+++ b/inc/ini-config
@@ -205,7 +205,7 @@
 }
 
 # Set a multiple line option in an INI file
-# iniset_multiline [-sudo] config-file section option value1 value2 valu3 ...
+# iniset_multiline [-sudo] config-file section option value1 value2 value3 ...
 function iniset_multiline {
     local xtrace
     xtrace=$(set +o | grep xtrace)
diff --git a/inc/meta-config b/inc/meta-config
index d74db59..b6fe437 100644
--- a/inc/meta-config
+++ b/inc/meta-config
@@ -20,7 +20,7 @@
 # file-name is the destination of the config file
 
 # Save trace setting
-INC_META_XTRACE=$(set +o | grep xtrace)
+_XTRACE_INC_META=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -92,7 +92,7 @@
     local real_configfile
     real_configfile=$(eval echo $configfile)
     if [ ! -f $real_configfile ]; then
-        touch $real_configfile
+        touch $real_configfile || die $LINENO "could not create config file $real_configfile ($configfile)"
     fi
 
     get_meta_section $file $matchgroup $configfile | \
@@ -178,8 +178,18 @@
     local configfile group
     for group in $matchgroups; do
         for configfile in $(get_meta_section_files $localfile $group); do
-            if [[ -d $(dirname $(eval "echo $configfile")) ]]; then
+            local realconfigfile
+            local dir
+
+            realconfigfile=$(eval "echo $configfile")
+            if [[ -z $realconfigfile ]]; then
+                die $LINENO "bogus config file specification: $configfile is undefined"
+            fi
+            dir=$(dirname $realconfigfile)
+            if [[ -d $dir ]]; then
                 merge_config_file $localfile $group $configfile
+            else
+                die $LINENO "bogus config file specification $configfile ($configfile=$realconfigfile, $dir is not a directory)"
             fi
         done
     done
@@ -187,7 +197,7 @@
 
 
 # Restore xtrace
-$INC_META_XTRACE
+$_XTRACE_INC_META
 
 # Local variables:
 # mode: shell-script
diff --git a/inc/python b/inc/python
index 91ceb44..c157604 100644
--- a/inc/python
+++ b/inc/python
@@ -17,7 +17,7 @@
 
 # Global Config Variables
 
-# PROJECT_VENV contains the name of the virtual enviromnet for each
+# PROJECT_VENV contains the name of the virtual environment for each
 # project.  A null value installs to the system Python directories.
 declare -A PROJECT_VENV
 
@@ -28,14 +28,17 @@
 # Get the path to the pip command.
 # get_pip_command
 function get_pip_command {
-    which pip || which pip-python
+    local version="$1"
+    # NOTE(dhellmann): I don't know if we actually get a pip3.4-python
+    # under any circumstances.
+    which pip${version} || which pip${version}-python
 
     if [ $? -ne 0 ]; then
-        die $LINENO "Unable to find pip; cannot continue"
+        die $LINENO "Unable to find pip${version}; cannot continue"
     fi
 }
 
-# Get the path to the direcotry where python executables are installed.
+# Get the path to the directory where python executables are installed.
 # get_python_exec_prefix
 function get_python_exec_prefix {
     local xtrace
@@ -66,6 +69,13 @@
     pip_install $clean_name
 }
 
+# Determine the python versions supported by a package
+function get_python_versions_for_package {
+    local name=$1
+    cd $name && python setup.py --classifiers \
+        | grep 'Language' | cut -f5 -d: | grep '\.' | tr '\n' ' '
+}
+
 # Wrapper for ``pip install`` to set cache and proxy environment variables
 # Uses globals ``OFFLINE``, ``PIP_VIRTUAL_ENV``,
 # ``PIP_UPGRADE``, ``TRACK_DEPENDS``, ``*_proxy``,
@@ -93,7 +103,7 @@
     fi
     if [[ $TRACK_DEPENDS = True && ! "$@" =~ virtualenv ]]; then
         # TRACK_DEPENDS=True installation creates a circular dependency when
-        # we attempt to install virtualenv into a virualenv, so we must global
+        # we attempt to install virtualenv into a virtualenv, so we must global
         # that installation.
         source $DEST/.venv/bin/activate
         local cmd_pip=$DEST/.venv/bin/pip
@@ -104,8 +114,22 @@
             local sudo_pip="env"
         else
             local cmd_pip
-            cmd_pip=$(get_pip_command)
+            cmd_pip=$(get_pip_command $PYTHON2_VERSION)
             local sudo_pip="sudo -H"
+            if python3_enabled; then
+                # Look at the package classifiers to find the python
+                # versions supported, and if we find the version of
+                # python3 we've been told to use, use that instead of the
+                # default pip
+                local package_dir=${!#}
+                local python_versions
+                if [[ -d "$package_dir" ]]; then
+                    python_versions=$(get_python_versions_for_package $package_dir)
+                    if [[ $python_versions =~ $PYTHON3_VERSION ]]; then
+                        cmd_pip=$(get_pip_command $PYTHON3_VERSION)
+                    fi
+                fi
+            fi
         fi
     fi
 
@@ -113,6 +137,8 @@
     # Always apply constraints
     cmd_pip="$cmd_pip -c $REQUIREMENTS_DIR/upper-constraints.txt"
 
+    # FIXME(dhellmann): Need to force multiple versions of pip for
+    # packages like setuptools?
     local pip_version
     pip_version=$(python -c "import pip; \
                         print(pip.__version__.strip('.')[0])")
@@ -199,7 +225,7 @@
     setup_install $dir
 }
 
-# setup a library by name in editiable mode. If we are trying to use
+# setup a library by name in editable mode. If we are trying to use
 # the library from git, we'll do a git based install, otherwise we'll
 # punt and the library should be installed by a requirements pull from
 # another project.
@@ -276,6 +302,21 @@
     fi
 }
 
+# Report whether python 3 should be used
+function python3_enabled {
+    if [[ $USE_PYTHON3 == "True" ]]; then
+        return 0
+    else
+        return 1
+    fi
+}
+
+# Install python3 packages
+function install_python3 {
+    if is_ubuntu; then
+        apt_get install python3.4 python3.4-dev
+    fi
+}
 
 # Restore xtrace
 $INC_PY_TRACE
diff --git a/inc/rootwrap b/inc/rootwrap
index 63ab59a..2a6e4b6 100644
--- a/inc/rootwrap
+++ b/inc/rootwrap
@@ -22,14 +22,14 @@
     local line
 
     # This is pretty simplistic for now - assume only the first line is used
-    if [[ -r SUDO_SECURE_PATH_FILE ]]; then
+    if [[ -r $SUDO_SECURE_PATH_FILE ]]; then
         line=$(head -1 $SUDO_SECURE_PATH_FILE)
     else
         line="Defaults:$STACK_USER secure_path=/usr/local/sbin:/usr/local/bin:/usr/sbin:/sbin:/usr/bin:/bin"
     fi
 
     # Only add ``dir`` if it is not already present
-    if [[ $line =~ $dir ]]; then
+    if [[ ! $line =~ $dir ]]; then
         echo "${line}:$dir" | sudo tee $SUDO_SECURE_PATH_FILE
         sudo chmod 400 $SUDO_SECURE_PATH_FILE
         sudo chown root:root $SUDO_SECURE_PATH_FILE
diff --git a/lib/apache b/lib/apache
index 17526c7..c9e02a2 100644
--- a/lib/apache
+++ b/lib/apache
@@ -19,7 +19,7 @@
 # - restart_apache_server
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_LIB_APACHE=$(set +o | grep xtrace)
 set +o xtrace
 
 # Allow overriding the default Apache user and group, default to
@@ -191,7 +191,7 @@
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_LIB_APACHE
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/ceph b/lib/ceph
index 29d2aca..4ac498a 100644
--- a/lib/ceph
+++ b/lib/ceph
@@ -18,7 +18,7 @@
 # - cleanup_ceph
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_LIB_CEPH=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -116,7 +116,7 @@
 
 # check_os_support_ceph() - Check if the operating system provides a decent version of Ceph
 function check_os_support_ceph {
-    if [[ ! ${DISTRO} =~ (trusty|f21|f22) ]]; then
+    if [[ ! ${DISTRO} =~ (trusty|f21|f22|f23) ]]; then
         echo "WARNING: your distro $DISTRO does not provide (at least) the Firefly release. Please use Ubuntu Trusty or Fedora 20 (and higher)"
         if [[ "$FORCE_CEPH_INSTALL" != "yes" ]]; then
             die $LINENO "If you wish to install Ceph on this distribution anyway run with FORCE_CEPH_INSTALL=yes"
@@ -375,7 +375,7 @@
 
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_LIB_CEPH
 
 ## Local variables:
 ## mode: shell-script
diff --git a/lib/cinder b/lib/cinder
index 2c9c94a..569f3ab 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -20,7 +20,7 @@
 # - cleanup_cinder
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -270,10 +270,6 @@
     iniset $CINDER_CONF DEFAULT state_path $CINDER_STATE_PATH
     iniset $CINDER_CONF oslo_concurrency lock_path $CINDER_STATE_PATH
     iniset $CINDER_CONF DEFAULT periodic_interval $CINDER_PERIODIC_INTERVAL
-    # NOTE(thingee): Cinder V1 API is deprecated and defaults to off as of
-    # Juno. Keep it enabled so we can continue testing while it's still
-    # supported.
-    iniset $CINDER_CONF DEFAULT enable_v1_api true
 
     iniset $CINDER_CONF DEFAULT os_region_name "$REGION_NAME"
 
@@ -299,7 +295,7 @@
     fi
 
     if is_service_enabled swift; then
-        iniset $CINDER_CONF DEFAULT backup_swift_url "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:8080/v1/AUTH_"
+        iniset $CINDER_CONF DEFAULT backup_swift_url "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:$SWIFT_DEFAULT_BIND_PORT/v1/AUTH_"
     fi
 
     if is_service_enabled ceilometer; then
@@ -317,9 +313,7 @@
 
     iniset_rpc_backend cinder $CINDER_CONF
 
-    if [[ "$CINDER_VOLUME_CLEAR" == "none" ]] || [[ "$CINDER_VOLUME_CLEAR" == "zero" ]] || [[ "$CINDER_VOLUME_CLEAR" == "shred" ]]; then
-        iniset $CINDER_CONF DEFAULT volume_clear $CINDER_VOLUME_CLEAR
-    fi
+    iniset $CINDER_CONF DEFAULT volume_clear $CINDER_VOLUME_CLEAR
 
     # Format logging
     if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ] && [ "$CINDER_USE_MOD_WSGI" == "False" ]; then
@@ -357,7 +351,7 @@
     iniset $CINDER_CONF DEFAULT os_privileged_user_name nova
     iniset $CINDER_CONF DEFAULT os_privileged_user_password "$SERVICE_PASSWORD"
     iniset $CINDER_CONF DEFAULT os_privileged_user_tenant "$SERVICE_TENANT_NAME"
-
+    iniset $CINDER_CONF DEFAULT graceful_shutdown_timeout "$SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT"
 }
 
 # create_cinder_accounts() - Set up common required cinder accounts
@@ -552,9 +546,7 @@
         local be be_name
         for be in ${CINDER_ENABLED_BACKENDS//,/ }; do
             be_name=${be##*:}
-            # FIXME(jamielennox): Remove --os-volume-api-version pinning when
-            # osc supports volume type create on v2 api. bug #1475060
-            openstack volume type create --os-volume-api-version 1 --property volume_backend_name="${be_name}" ${be_name}
+            openstack volume type create --property volume_backend_name="${be_name}" ${be_name}
         done
     fi
 }
@@ -569,7 +561,7 @@
 
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_CINDER
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/cinder_backends/ceph b/lib/cinder_backends/ceph
index 7e9d2d3..c21350b 100644
--- a/lib/cinder_backends/ceph
+++ b/lib/cinder_backends/ceph
@@ -22,7 +22,7 @@
 
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_CEPH=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -76,7 +76,7 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_CINDER_CEPH
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/cinder_backends/glusterfs b/lib/cinder_backends/glusterfs
index 00c62e0..4e34f8e 100644
--- a/lib/cinder_backends/glusterfs
+++ b/lib/cinder_backends/glusterfs
@@ -19,7 +19,7 @@
 # configure_cinder_backend_glusterfs - Configure Cinder for GlusterFS backends
 
 # Save trace setting
-GLUSTERFS_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_GLUSTERFS=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -41,7 +41,7 @@
 
 
 # Restore xtrace
-$GLUSTERFS_XTRACE
+$_XTRACE_CINDER_GLUSTERFS
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/cinder_backends/lvm b/lib/cinder_backends/lvm
index 411b82c..d927f9c 100644
--- a/lib/cinder_backends/lvm
+++ b/lib/cinder_backends/lvm
@@ -22,7 +22,7 @@
 
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_LVM=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -68,7 +68,7 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_CINDER_LVM
 
 # mode: shell-script
 # End:
diff --git a/lib/cinder_backends/netapp_iscsi b/lib/cinder_backends/netapp_iscsi
index be9442e..5cce30a 100644
--- a/lib/cinder_backends/netapp_iscsi
+++ b/lib/cinder_backends/netapp_iscsi
@@ -20,7 +20,7 @@
 # configure_cinder_backend_netapp_iscsi - configure iSCSI
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_NETAPP=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -59,7 +59,7 @@
 
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_CINDER_NETAPP
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/cinder_backends/netapp_nfs b/lib/cinder_backends/netapp_nfs
index dc919ad..7ba36d2 100644
--- a/lib/cinder_backends/netapp_nfs
+++ b/lib/cinder_backends/netapp_nfs
@@ -20,7 +20,7 @@
 # configure_cinder_backend_netapp_nfs - configure NFS
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_NETAPP=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -70,7 +70,7 @@
 
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_CINDER_NETAPP
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/cinder_backends/nfs b/lib/cinder_backends/nfs
index fc51b2b..89a37a1 100644
--- a/lib/cinder_backends/nfs
+++ b/lib/cinder_backends/nfs
@@ -19,7 +19,7 @@
 # configure_cinder_backend_nfs - Configure Cinder for NFS backends
 
 # Save trace setting
-NFS_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_NFS=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -38,7 +38,7 @@
 
 
 # Restore xtrace
-$NFS_XTRACE
+$_XTRACE_CINDER_NFS
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/cinder_backends/solidfire b/lib/cinder_backends/solidfire
index 7cc70fc..16bc527 100644
--- a/lib/cinder_backends/solidfire
+++ b/lib/cinder_backends/solidfire
@@ -17,7 +17,7 @@
 # configure_cinder_driver - make configuration changes, including those to other services
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_SOLIDFIRE=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -42,7 +42,7 @@
 
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_CINDER_SOLIDFIRE
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/cinder_backends/vmdk b/lib/cinder_backends/vmdk
index d5b9453..3a6a5cf 100644
--- a/lib/cinder_backends/vmdk
+++ b/lib/cinder_backends/vmdk
@@ -15,7 +15,7 @@
 # configure_cinder_backend_vmdk - Configure Cinder for VMware vmdk backends
 
 # Save trace setting
-VMDK_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_VMDK=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -40,7 +40,7 @@
 
 
 # Restore xtrace
-$VMDK_XTRACE
+$_XTRACE_CINDER_VMDK
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/cinder_backends/xiv b/lib/cinder_backends/xiv
index 6eadaae..e8b5da0 100644
--- a/lib/cinder_backends/xiv
+++ b/lib/cinder_backends/xiv
@@ -42,7 +42,7 @@
 # configure_cinder_backend_xiv - Configure Cinder for xiv backends
 
 # Save trace setting
-XIV_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_XIV=$(set +o | grep xtrace)
 set +o xtrace
 
 # Defaults
@@ -79,7 +79,7 @@
 }
 
 # Restore xtrace
-$XIV_XTRACE
+$_XTRACE_CINDER_XIV
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/cinder_plugins/XenAPINFS b/lib/cinder_plugins/XenAPINFS
index f730695..92135e7 100644
--- a/lib/cinder_plugins/XenAPINFS
+++ b/lib/cinder_plugins/XenAPINFS
@@ -15,7 +15,7 @@
 # configure_cinder_driver - make configuration changes, including those to other services
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_XENAPINFS=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -39,7 +39,7 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_CINDER_XENAPINFS
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/cinder_plugins/glusterfs b/lib/cinder_plugins/glusterfs
index 35ceb27..329dd6c 100644
--- a/lib/cinder_plugins/glusterfs
+++ b/lib/cinder_plugins/glusterfs
@@ -15,7 +15,7 @@
 # configure_cinder_driver - make configuration changes, including those to other services
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_GLUSTERFS=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -45,7 +45,7 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_CINDER_GLUSTERFS
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/cinder_plugins/nfs b/lib/cinder_plugins/nfs
index 83b3993..6e4ffe0 100644
--- a/lib/cinder_plugins/nfs
+++ b/lib/cinder_plugins/nfs
@@ -15,7 +15,7 @@
 # configure_cinder_driver - make configuration changes, including those to other services
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_NFS=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -36,7 +36,7 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_CINDER_NFS
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/cinder_plugins/sheepdog b/lib/cinder_plugins/sheepdog
index ca343f7..558de46 100644
--- a/lib/cinder_plugins/sheepdog
+++ b/lib/cinder_plugins/sheepdog
@@ -15,7 +15,7 @@
 # configure_cinder_driver - make configuration changes, including those to other services
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_SHEEPDOG=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -34,7 +34,7 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_CINDER_SHEEPDOG
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/cinder_plugins/vsphere b/lib/cinder_plugins/vsphere
index f14ddf0..1b28ffe 100644
--- a/lib/cinder_plugins/vsphere
+++ b/lib/cinder_plugins/vsphere
@@ -15,7 +15,7 @@
 # configure_cinder_driver - make configuration changes, including those to other services
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_CINDER_VSPHERE=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -37,7 +37,7 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_CINDER_VSPHERE
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/database b/lib/database
index 13740b9..0d72052 100644
--- a/lib/database
+++ b/lib/database
@@ -20,7 +20,7 @@
 # and call register_database $DATABASE_TYPE
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_LIB_DB=$(set +o | grep xtrace)
 set +o xtrace
 
 DATABASE_BACKENDS=""
@@ -137,7 +137,7 @@
 
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_LIB_DB
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/databases/mysql b/lib/databases/mysql
index c2ab32e..1bbbd62 100644
--- a/lib/databases/mysql
+++ b/lib/databases/mysql
@@ -8,7 +8,7 @@
 # - DATABASE_{HOST,USER,PASSWORD} must be defined
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_DB_MYSQL=$(set +o | grep xtrace)
 set +o xtrace
 
 MYSQL_DRIVER=${MYSQL_DRIVER:-PyMySQL}
@@ -143,7 +143,7 @@
 [client]
 user=$DATABASE_USER
 password=$DATABASE_PASSWORD
-host=$DATABASE_HOST
+host=$MYSQL_HOST
 EOF
         chmod 0600 $HOME/.my.cnf
     fi
@@ -178,7 +178,7 @@
 
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_DB_MYSQL
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/databases/postgresql b/lib/databases/postgresql
index 78c7bed..913e8ff 100644
--- a/lib/databases/postgresql
+++ b/lib/databases/postgresql
@@ -8,7 +8,7 @@
 # - DATABASE_{HOST,USER,PASSWORD} must be defined
 
 # Save trace setting
-PG_XTRACE=$(set +o | grep xtrace)
+_XTRACE_PG=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -119,7 +119,7 @@
 
 
 # Restore xtrace
-$PG_XTRACE
+$_XTRACE_PG
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/dlm b/lib/dlm
new file mode 100644
index 0000000..74eb67e
--- /dev/null
+++ b/lib/dlm
@@ -0,0 +1,108 @@
+#!/bin/bash
+#
+# lib/dlm
+#
+# Functions to control the installation and configuration of software
+# that provides a dlm (and possibly other functions). The default is
+# **zookeeper**, and is going to be the only backend supported in the
+# devstack tree.
+
+# Dependencies:
+#
+# - ``functions`` file
+
+# ``stack.sh`` calls the entry points in this order:
+#
+# - is_dlm_enabled
+# - install_dlm
+# - configure_dlm
+# - cleanup_dlm
+
+# Save trace setting
+_XTRACE_DLM=$(set +o | grep xtrace)
+set +o xtrace
+
+
+# Defaults
+# --------
+
+# <define global variables here that belong to this project>
+
+# Set up default directories
+ZOOKEEPER_DATA_DIR=$DEST/data/zookeeper
+ZOOKEEPER_CONF_DIR=/etc/zookeeper
+
+
+# Entry Points
+# ------------
+#
+# NOTE(sdague): it is expected that when someone wants to implement
+# another one of these out of tree, they'll implement the following
+# functions:
+#
+# - dlm_backend
+# - install_dlm
+# - configure_dlm
+# - cleanup_dlm
+
+# This should be declared in the settings file of any plugin or
+# service that needs to have a dlm in their environment.
+function use_dlm {
+    enable_service $(dlm_backend)
+}
+
+# A function to return the name of the backend in question, some users
+# are going to need to know this.
+function dlm_backend {
+    echo "zookeeper"
+}
+
+# Test if a dlm is enabled (defaults to a zookeeper specific check)
+function is_dlm_enabled {
+    [[ ,${ENABLED_SERVICES}, =~ ,"$(dlm_backend)", ]] && return 0
+    return 1
+}
+
+# cleanup_dlm() - Remove residual data files, anything left over from previous
+# runs that a clean run would need to clean up
+function cleanup_dlm {
+    # NOTE(sdague): we don't check for is_enabled here because we
+    # should just delete this regardless. Some times users updated
+    # their service list before they run cleanup.
+    sudo rm -rf $ZOOKEEPER_DATA_DIR
+}
+
+# configure_dlm() - Set config files, create data dirs, etc
+function configure_dlm {
+    if is_dlm_enabled; then
+        sudo cp $FILES/zookeeper/* $ZOOKEEPER_CONF_DIR
+        sudo sed -i -e 's|.*dataDir.*|dataDir='$ZOOKEEPER_DATA_DIR'|' $ZOOKEEPER_CONF_DIR/zoo.cfg
+        # clean up from previous (possibly aborted) runs
+        # create required data files
+        sudo rm -rf $ZOOKEEPER_DATA_DIR
+        sudo mkdir -p $ZOOKEEPER_DATA_DIR
+        # restart after configuration, there is no reason to make this
+        # another step, because having data files that don't match the
+        # zookeeper running is just going to cause tears.
+        restart_service zookeeper
+    fi
+}
+
+# install_dlm() - Collect source and prepare
+function install_dlm {
+    if is_dlm_enabled; then
+        if is_ubuntu; then
+            install_package zookeeperd
+        else
+            die $LINENO "Don't know how to install zookeeper on this platform"
+        fi
+    fi
+}
+
+# Restore xtrace
+$_XTRACE_DLM
+
+# Tell emacs to use shell-script-mode
+## Local variables:
+## mode: shell-script
+## End:
diff --git a/lib/dstat b/lib/dstat
index fe4790b..b705948 100644
--- a/lib/dstat
+++ b/lib/dstat
@@ -13,7 +13,7 @@
 # - stop_dstat
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_DSTAT=$(set +o | grep xtrace)
 set +o xtrace
 
 # start_dstat() - Start running processes, including screen
@@ -34,4 +34,4 @@
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_DSTAT
diff --git a/lib/glance b/lib/glance
index 2eb93a4..4f95975 100644
--- a/lib/glance
+++ b/lib/glance
@@ -21,7 +21,7 @@
 # - cleanup_glance
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_GLANCE=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -115,6 +115,7 @@
     configure_auth_token_middleware $GLANCE_REGISTRY_CONF glance $GLANCE_AUTH_CACHE_DIR/registry
     iniset $GLANCE_REGISTRY_CONF DEFAULT notification_driver messaging
     iniset_rpc_backend glance $GLANCE_REGISTRY_CONF
+    iniset $GLANCE_REGISTRY_CONF DEFAULT graceful_shutdown_timeout "$SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT"
 
     cp $GLANCE_DIR/etc/glance-api.conf $GLANCE_API_CONF
     iniset $GLANCE_API_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
@@ -149,6 +150,7 @@
         iniset $GLANCE_API_CONF glance_store swift_store_config_file $GLANCE_SWIFT_STORE_CONF
         iniset $GLANCE_API_CONF glance_store default_swift_reference ref1
         iniset $GLANCE_API_CONF glance_store stores "file, http, swift"
+        iniset $GLANCE_API_CONF DEFAULT graceful_shutdown_timeout "$SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT"
 
         iniset $GLANCE_SWIFT_STORE_CONF ref1 user $SERVICE_TENANT_NAME:glance-swift
         iniset $GLANCE_SWIFT_STORE_CONF ref1 key $SERVICE_PASSWORD
@@ -403,7 +405,7 @@
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_GLANCE
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/heat b/lib/heat
index 615198c..3666776 100644
--- a/lib/heat
+++ b/lib/heat
@@ -16,13 +16,14 @@
 # - install_heat
 # - configure_heatclient
 # - configure_heat
+# - _config_heat_apache_wsgi
 # - init_heat
 # - start_heat
 # - stop_heat
 # - cleanup_heat
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_HEAT=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -32,6 +33,9 @@
 # set up default directories
 GITDIR["python-heatclient"]=$DEST/python-heatclient
 
+# Toggle for deploying Heat-API under HTTPD + mod_wsgi
+HEAT_USE_MOD_WSGI=${HEAT_USE_MOD_WSGI:-False}
+
 HEAT_DIR=$DEST/heat
 HEAT_CFNTOOLS_DIR=$DEST/heat-cfntools
 HEAT_TEMPLATES_REPO_DIR=$DEST/heat-templates
@@ -52,6 +56,10 @@
 HEAT_TEMPLATES_DIR=$HEAT_CONF_DIR/templates
 HEAT_API_HOST=${HEAT_API_HOST:-$HOST_IP}
 HEAT_API_PORT=${HEAT_API_PORT:-8004}
+HEAT_SERVICE_USER=${HEAT_SERVICE_USER:-heat}
+HEAT_TRUSTEE_USER=${HEAT_TRUSTEE_USER:-$HEAT_SERVICE_USER}
+HEAT_TRUSTEE_PASSWORD=${HEAT_TRUSTEE_PASSWORD:-$SERVICE_PASSWORD}
+HEAT_TRUSTEE_DOMAIN=${HEAT_TRUSTEE_DOMAIN:-default}
 
 # Support entry points installation of console scripts
 HEAT_BIN_DIR=$(get_python_exec_prefix)
@@ -61,10 +69,18 @@
     # for standalone, use defaults which require no service user
     HEAT_STACK_DOMAIN=$(trueorfalse False HEAT_STACK_DOMAIN)
     HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-password}
+    if [[ ${HEAT_DEFERRED_AUTH} != "password" ]]; then
+        # Heat does not support keystone trusts when deployed in
+        # standalone mode
+        die $LINENO \
+            'HEAT_DEFERRED_AUTH can only be set to "password" when HEAT_STANDALONE is True.'
+    fi
 else
     HEAT_STACK_DOMAIN=$(trueorfalse True HEAT_STACK_DOMAIN)
-    HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-trusts}
+    HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-}
 fi
+HEAT_PLUGIN_DIR=${HEAT_PLUGIN_DIR:-$DATA_DIR/heat/plugins}
+ENABLE_HEAT_PLUGINS=${ENABLE_HEAT_PLUGINS:-}
 
 # Functions
 # ---------
@@ -117,31 +133,44 @@
     # logging
     iniset $HEAT_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
     iniset $HEAT_CONF DEFAULT use_syslog $SYSLOG
-    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
+    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ] && [ "$HEAT_USE_MOD_WSGI" == "False" ]  ; then
         # Add color to logging output
         setup_colorized_logging $HEAT_CONF DEFAULT tenant user
     fi
 
-    iniset $HEAT_CONF DEFAULT deferred_auth_method $HEAT_DEFERRED_AUTH
+    if [ ! -z "$HEAT_DEFERRED_AUTH" ]; then
+        iniset $HEAT_CONF DEFAULT deferred_auth_method $HEAT_DEFERRED_AUTH
+    fi
 
-    # NOTE(jamielennox): heat re-uses specific values from the
-    # keystone_authtoken middleware group and so currently fails when using the
-    # auth plugin setup. This should be fixed in heat.  Heat is also the only
-    # service that requires the auth_uri to include a /v2.0. Remove this custom
-    # setup when bug #1300246 is resolved.
-    iniset $HEAT_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_URI/v2.0
+    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
+        _config_heat_apache_wsgi
+    fi
+
     if [[ "$HEAT_STANDALONE" = "True" ]]; then
         iniset $HEAT_CONF paste_deploy flavor standalone
         iniset $HEAT_CONF clients_heat url "http://$HEAT_API_HOST:$HEAT_API_PORT/v1/%(tenant_id)s"
     else
         iniset $HEAT_CONF keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
-        iniset $HEAT_CONF keystone_authtoken admin_user heat
+        iniset $HEAT_CONF keystone_authtoken admin_user $HEAT_SERVICE_USER
         iniset $HEAT_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
         iniset $HEAT_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
         iniset $HEAT_CONF keystone_authtoken cafile $SSL_BUNDLE_FILE
         iniset $HEAT_CONF keystone_authtoken signing_dir $HEAT_AUTH_CACHE_DIR
     fi
 
+    # If HEAT_DEFERRED_AUTH is unset or explicitly set to trusts, configure
+    # the section for the client plugin associated with the trustee
+    if [ -z "$HEAT_DEFERRED_AUTH" -o "trusts" == "$HEAT_DEFERRED_AUTH" ]; then
+        iniset $HEAT_CONF trustee auth_plugin password
+        iniset $HEAT_CONF trustee auth_url $KEYSTONE_AUTH_URI
+        iniset $HEAT_CONF trustee username $HEAT_TRUSTEE_USER
+        iniset $HEAT_CONF trustee password $HEAT_TRUSTEE_PASSWORD
+        iniset $HEAT_CONF trustee user_domain_id $HEAT_TRUSTEE_DOMAIN
+    fi
+
+    # clients_keystone
+    iniset $HEAT_CONF clients_keystone auth_uri $KEYSTONE_AUTH_URI
+
     # ec2authtoken
     iniset $HEAT_CONF ec2authtoken auth_uri $KEYSTONE_SERVICE_URI/v2.0
 
@@ -180,6 +209,35 @@
     # copy the default templates
     cp $HEAT_DIR/etc/heat/templates/* $HEAT_TEMPLATES_DIR/
 
+    # Enable heat plugins.
+    # NOTE(nic): The symlink nonsense is necessary because when
+    # plugins are installed in "developer mode", the final component
+    # of their target directory is always "resources", which confuses
+    # Heat's plugin loader into believing that all plugins are named
+    # "resources", and therefore are all the same plugin; so it
+    # will only load one of them.  Linking them all to a common
+    # location with unique names avoids that type of collision,
+    # while still allowing the plugins to be edited in-tree.
+    local err_count=0
+
+    if [ -n "$ENABLE_HEAT_PLUGINS" ]; then
+        mkdir -p $HEAT_PLUGIN_DIR
+        # Clean up cruft from any previous runs
+        rm -f $HEAT_PLUGIN_DIR/*
+        iniset $HEAT_CONF DEFAULT plugin_dirs $HEAT_PLUGIN_DIR
+    fi
+
+    for heat_plugin in $ENABLE_HEAT_PLUGINS; do
+        if [ -d $HEAT_DIR/contrib/$heat_plugin ]; then
+            setup_package $HEAT_DIR/contrib/$heat_plugin -e
+            ln -s $HEAT_DIR/contrib/$heat_plugin/$heat_plugin/resources $HEAT_PLUGIN_DIR/$heat_plugin
+        else
+            : # clear retval on the test so that we can roll up errors
+            err $LINENO "Requested Heat plugin(${heat_plugin}) not found."
+            err_count=$(($err_count + 1))
+        fi
+    done
+    [ $err_count -eq 0 ] || die $LINENO "$err_count of the requested Heat plugins could not be installed."
 }
 
 # init_heat() - Initialize database
@@ -211,6 +269,9 @@
 function install_heat {
     git_clone $HEAT_REPO $HEAT_DIR $HEAT_BRANCH
     setup_develop $HEAT_DIR
+    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
+        install_apache_wsgi
+    fi
 }
 
 # install_heat_other() - Collect source and prepare
@@ -226,20 +287,106 @@
 # start_heat() - Start running processes, including screen
 function start_heat {
     run_process h-eng "$HEAT_BIN_DIR/heat-engine --config-file=$HEAT_CONF"
-    run_process h-api "$HEAT_BIN_DIR/heat-api --config-file=$HEAT_CONF"
-    run_process h-api-cfn "$HEAT_BIN_DIR/heat-api-cfn --config-file=$HEAT_CONF"
-    run_process h-api-cw "$HEAT_BIN_DIR/heat-api-cloudwatch --config-file=$HEAT_CONF"
+
+    # If the site is not enabled then we are in a grenade scenario
+    local enabled_site_file
+    enabled_site_file=$(apache_site_config_for heat-api)
+    if [ -f ${enabled_site_file} ] && [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
+        enable_apache_site heat-api
+        enable_apache_site heat-api-cfn
+        enable_apache_site heat-api-cloudwatch
+        restart_apache_server
+        tail_log heat-api /var/log/$APACHE_NAME/heat-api.log
+        tail_log heat-api-cfn /var/log/$APACHE_NAME/heat-api-cfn.log
+        tail_log heat-api-cloudwatch /var/log/$APACHE_NAME/heat-api-cloudwatch.log
+    else
+        run_process h-api "$HEAT_BIN_DIR/heat-api --config-file=$HEAT_CONF"
+        run_process h-api-cfn "$HEAT_BIN_DIR/heat-api-cfn --config-file=$HEAT_CONF"
+        run_process h-api-cw "$HEAT_BIN_DIR/heat-api-cloudwatch --config-file=$HEAT_CONF"
+    fi
 }
 
 # stop_heat() - Stop running processes
 function stop_heat {
     # Kill the screen windows
-    local serv
-    for serv in h-eng h-api h-api-cfn h-api-cw; do
-        stop_process $serv
-    done
+    stop_process h-eng
+
+    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
+        disable_apache_site heat-api
+        disable_apache_site heat-api-cfn
+        disable_apache_site heat-api-cloudwatch
+        restart_apache_server
+    else
+        local serv
+        for serv in h-api h-api-cfn h-api-cw; do
+            stop_process $serv
+        done
+    fi
+
 }
 
+# _cleanup_heat_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
+function _cleanup_heat_apache_wsgi {
+    sudo rm -f $(apache_site_config_for heat-api)
+    sudo rm -f $(apache_site_config_for heat-api-cfn)
+    sudo rm -f $(apache_site_config_for heat-api-cloudwatch)
+}
+
+# _config_heat_apache_wsgi() - Set WSGI config files of Heat
+function _config_heat_apache_wsgi {
+
+    local heat_apache_conf
+    heat_apache_conf=$(apache_site_config_for heat-api)
+    local heat_cfn_apache_conf
+    heat_cfn_apache_conf=$(apache_site_config_for heat-api-cfn)
+    local heat_cloudwatch_apache_conf
+    heat_cloudwatch_apache_conf=$(apache_site_config_for heat-api-cloudwatch)
+    local heat_ssl=""
+    local heat_certfile=""
+    local heat_keyfile=""
+    local heat_api_port=$HEAT_API_PORT
+    local heat_cfn_api_port=$HEAT_API_CFN_PORT
+    local heat_cw_api_port=$HEAT_API_CW_PORT
+    local venv_path=""
+
+    sudo cp $FILES/apache-heat-api.template $heat_apache_conf
+    sudo sed -e "
+        s|%PUBLICPORT%|$heat_api_port|g;
+        s|%APACHE_NAME%|$APACHE_NAME|g;
+        s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
+        s|%SSLENGINE%|$heat_ssl|g;
+        s|%SSLCERTFILE%|$heat_certfile|g;
+        s|%SSLKEYFILE%|$heat_keyfile|g;
+        s|%USER%|$STACK_USER|g;
+        s|%VIRTUALENV%|$venv_path|g
+    " -i $heat_apache_conf
+
+    sudo cp $FILES/apache-heat-api-cfn.template $heat_cfn_apache_conf
+    sudo sed -e "
+        s|%PUBLICPORT%|$heat_cfn_api_port|g;
+        s|%APACHE_NAME%|$APACHE_NAME|g;
+        s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
+        s|%SSLENGINE%|$heat_ssl|g;
+        s|%SSLCERTFILE%|$heat_certfile|g;
+        s|%SSLKEYFILE%|$heat_keyfile|g;
+        s|%USER%|$STACK_USER|g;
+        s|%VIRTUALENV%|$venv_path|g
+    " -i $heat_cfn_apache_conf
+
+    sudo cp $FILES/apache-heat-api-cloudwatch.template $heat_cloudwatch_apache_conf
+    sudo sed -e "
+        s|%PUBLICPORT%|$heat_cw_api_port|g;
+        s|%APACHE_NAME%|$APACHE_NAME|g;
+        s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
+        s|%SSLENGINE%|$heat_ssl|g;
+        s|%SSLCERTFILE%|$heat_certfile|g;
+        s|%SSLKEYFILE%|$heat_keyfile|g;
+        s|%USER%|$STACK_USER|g;
+        s|%VIRTUALENV%|$venv_path|g
+    " -i $heat_cloudwatch_apache_conf
+}
+
+
 # create_heat_accounts() - Set up common required heat accounts
 function create_heat_accounts {
     if [[ "$HEAT_STANDALONE" != "True" ]]; then
@@ -336,7 +483,7 @@
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_HEAT
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/horizon b/lib/horizon
index 6ecd755..67181fc 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -19,7 +19,7 @@
 # - cleanup_horizon
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_HORIZON=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -99,13 +99,8 @@
 
     _horizon_config_set $local_settings "" OPENSTACK_HOST \"${KEYSTONE_SERVICE_HOST}\"
 
-    if [ "$ENABLE_IDENTITY_V2" == "False" ]; then
-        # Only Identity v3 API is available; then use it with v3 auth tokens
-        _horizon_config_set $local_settings "" OPENSTACK_API_VERSIONS {\"identity\":3}
-        _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_URL "\"${KEYSTONE_SERVICE_PROTOCOL}://${KEYSTONE_SERVICE_HOST}:${KEYSTONE_SERVICE_PORT}/v3\""
-    else
-        _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_URL "\"${KEYSTONE_SERVICE_PROTOCOL}://${KEYSTONE_SERVICE_HOST}:${KEYSTONE_SERVICE_PORT}/v2.0\""
-    fi
+    _horizon_config_set $local_settings "" OPENSTACK_API_VERSIONS {\"identity\":3}
+    _horizon_config_set $local_settings "" OPENSTACK_KEYSTONE_URL "\"${KEYSTONE_SERVICE_PROTOCOL}://${KEYSTONE_SERVICE_HOST}:${KEYSTONE_SERVICE_PORT}/v3\""
 
     if [ -f $SSL_BUNDLE_FILE ]; then
         _horizon_config_set $local_settings "" OPENSTACK_SSL_CACERT \"${SSL_BUNDLE_FILE}\"
@@ -198,7 +193,7 @@
 
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_HORIZON
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/infra b/lib/infra
index ab32efe..cf003cc 100644
--- a/lib/infra
+++ b/lib/infra
@@ -15,7 +15,7 @@
 # - install_infra
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_INFRA=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -50,7 +50,7 @@
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_INFRA
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/ironic b/lib/ironic
index 74e2f93..dd4f8bf 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -21,11 +21,18 @@
 # - cleanup_ironic
 
 # Save trace and pipefail settings
-XTRACE=$(set +o | grep xtrace)
-PIPEFAIL=$(set +o | grep pipefail)
+_XTRACE_IRONIC=$(set +o | grep xtrace)
+_PIPEFAIL_IRONIC=$(set +o | grep pipefail)
 set +o xtrace
 set +o pipefail
 
+# NOTE(jroll) this is used for the transition to a devstack plugin in
+# the ironic tree.
+IRONIC_USING_PLUGIN=$(trueorfalse False IRONIC_USING_PLUGIN)
+if [[ "$IRONIC_USING_PLUGIN" == "True" ]] ; then
+    return 0
+fi
+
 # Defaults
 # --------
 
@@ -92,7 +99,7 @@
 # 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)
+# (The value must be an absolute path)
 IRONIC_DEPLOY_RAMDISK=${IRONIC_DEPLOY_RAMDISK:-}
 IRONIC_DEPLOY_KERNEL=${IRONIC_DEPLOY_KERNEL:-}
 IRONIC_DEPLOY_ELEMENT=${IRONIC_DEPLOY_ELEMENT:-deploy-ironic}
@@ -365,6 +372,9 @@
         iniset $IRONIC_CONF_FILE pxe pxe_append_params "$pxe_params"
     fi
 
+    # Set these options for scenarios in which the agent fetches the image
+    # directly from glance, and don't set them where the image is pushed
+    # over iSCSI.
     if is_deployed_by_agent; then
         if [[ "$SWIFT_ENABLE_TEMPURLS" == "True" ]] ; then
             iniset $IRONIC_CONF_FILE glance swift_temp_url_key $SWIFT_TEMPURL_KEY
@@ -379,9 +389,13 @@
         iniset $IRONIC_CONF_FILE glance swift_container glance
         iniset $IRONIC_CONF_FILE glance swift_temp_url_duration 3600
         iniset $IRONIC_CONF_FILE agent heartbeat_timeout 30
-        iniset $IRONIC_CONF_FILE agent agent_erase_devices_priority 0
     fi
 
+    # FIXME: this really needs to be tested in the gate.
+    # For now, any test using the agent ramdisk should skip cleaning
+    # because it is too slow to run in the gate.
+    iniset $IRONIC_CONF_FILE agent agent_erase_devices_priority 0
+
     if [[ "$IRONIC_IPXE_ENABLED" == "True" ]] ; then
         local pxebin
         pxebin=`basename $IRONIC_PXE_BOOT_IMAGE`
@@ -516,13 +530,8 @@
     # intentional sleep to make sure the tag has been set to port
     sleep 10
 
-    if  [[ "$Q_USE_NAMESPACE" = "True" ]]; then
-        local tapdev
-        tapdev=$(sudo ip netns exec qdhcp-${ironic_net_id} ip link list | grep " tap" | cut -d':' -f2 | cut -d'@' -f1 | cut -b2-)
-    else
-        local tapdev
-        tapdev=$(sudo ip link list | grep " tap" | cut -d':' -f2 | cut -d'@' -f1 | cut -b2-)
-    fi
+    local tapdev
+    tapdev=$(sudo ip netns exec qdhcp-${ironic_net_id} ip link list | grep " tap" | cut -d':' -f2 | cut -d'@' -f1 | cut -b2-)
     local tag_id
     tag_id=$(sudo ovs-vsctl show |grep ${tapdev} -A1 -m1 | grep tag | cut -d':' -f2 | cut -b2-)
 
@@ -657,13 +666,9 @@
         total_cpus=$((total_cpus+$ironic_node_cpu))
     done < $ironic_hwinfo_file
 
-    # create the nova flavor
-    # NOTE(adam_g): Attempting to use an autogenerated UUID for flavor id here uncovered
-    # bug (LP: #1333852) in Trove.  This can be changed to use an auto flavor id when the
-    # bug is fixed in Juno.
     local adjusted_disk
     adjusted_disk=$(($ironic_node_disk - $ironic_ephemeral_disk))
-    nova flavor-create --ephemeral $ironic_ephemeral_disk baremetal 551 $ironic_node_ram $adjusted_disk $ironic_node_cpu
+    nova flavor-create --ephemeral $ironic_ephemeral_disk baremetal auto $ironic_node_ram $adjusted_disk $ironic_node_cpu
 
     nova flavor-key baremetal set "cpu_arch"="x86_64"
 
@@ -677,6 +682,8 @@
     # enable tftp natting for allowing connections to HOST_IP's tftp server
     sudo modprobe nf_conntrack_tftp
     sudo modprobe nf_nat_tftp
+    # explicitly allow DHCP - packets are occasionally being dropped here
+    sudo iptables -I INPUT -p udp --dport 67:68 --sport 67:68 -j ACCEPT || true
     # 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 $IRONIC_SERVICE_PORT -j ACCEPT || true
@@ -800,7 +807,7 @@
     # load them into glance
     IRONIC_DEPLOY_KERNEL_ID=$(openstack \
         --os-token $token \
-        --os-url http://$GLANCE_HOSTPORT \
+        --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT \
         image create \
         $(basename $IRONIC_DEPLOY_KERNEL_PATH) \
         --public --disk-format=aki \
@@ -808,7 +815,7 @@
         < $IRONIC_DEPLOY_KERNEL_PATH  | grep ' id ' | get_field 2)
     IRONIC_DEPLOY_RAMDISK_ID=$(openstack \
         --os-token $token \
-        --os-url http://$GLANCE_HOSTPORT \
+        --os-url $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT \
         image create \
         $(basename $IRONIC_DEPLOY_RAMDISK_PATH) \
         --public --disk-format=ari \
@@ -858,8 +865,8 @@
 }
 
 # Restore xtrace + pipefail
-$XTRACE
-$PIPEFAIL
+$_XTRACE_IRONIC
+$_PIPEFAIL_IRONIC
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/keystone b/lib/keystone
index cdcc13a..6b4118d 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -28,7 +28,7 @@
 # - _cleanup_keystone_apache_wsgi
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_KEYSTONE=$(set +o | grep xtrace)
 set +o xtrace
 
 # Defaults
@@ -218,8 +218,6 @@
 
     iniset_rpc_backend keystone $KEYSTONE_CONF
 
-    iniset $KEYSTONE_CONF eventlet_server admin_bind_host "$KEYSTONE_ADMIN_BIND_HOST"
-
     # Register SSL certificates if provided
     if is_ssl_enabled_service key; then
         ensure_certificates KEYSTONE
@@ -254,9 +252,9 @@
 
         # Add swift endpoints to service catalog if swift is enabled
         if is_service_enabled s-proxy; then
-            echo "catalog.RegionOne.object_store.publicURL = http://%SERVICE_HOST%:8080/v1/AUTH_\$(tenant_id)s" >> $KEYSTONE_CATALOG
-            echo "catalog.RegionOne.object_store.adminURL = http://%SERVICE_HOST%:8080/" >> $KEYSTONE_CATALOG
-            echo "catalog.RegionOne.object_store.internalURL = http://%SERVICE_HOST%:8080/v1/AUTH_\$(tenant_id)s" >> $KEYSTONE_CATALOG
+            echo "catalog.RegionOne.object_store.publicURL = http://%SERVICE_HOST%:$SWIFT_DEFAULT_BIND_PORT/v1/AUTH_\$(tenant_id)s" >> $KEYSTONE_CATALOG
+            echo "catalog.RegionOne.object_store.adminURL = http://%SERVICE_HOST%:$SWIFT_DEFAULT_BIND_PORT/" >> $KEYSTONE_CATALOG
+            echo "catalog.RegionOne.object_store.internalURL = http://%SERVICE_HOST%:$SWIFT_DEFAULT_BIND_PORT/v1/AUTH_\$(tenant_id)s" >> $KEYSTONE_CATALOG
             echo "catalog.RegionOne.object_store.name = Swift Service" >> $KEYSTONE_CATALOG
         fi
 
@@ -296,13 +294,14 @@
         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
+    else
+        iniset $KEYSTONE_CONF eventlet_server admin_bind_host "$KEYSTONE_ADMIN_BIND_HOST"
+        iniset $KEYSTONE_CONF eventlet_server admin_workers "$API_WORKERS"
+        # Public workers will use the server default, typically number of CPU.
     fi
 
     iniset $KEYSTONE_CONF DEFAULT max_token_size 16384
 
-    iniset $KEYSTONE_CONF eventlet_server admin_workers "$API_WORKERS"
-    # Public workers will use the server default, typically number of CPU.
-
     iniset $KEYSTONE_CONF fernet_tokens key_repository "$KEYSTONE_CONF_DIR/fernet-keys/"
 }
 
@@ -592,7 +591,7 @@
 
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_KEYSTONE
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/ldap b/lib/ldap
index 0414fea..65056ae 100644
--- a/lib/ldap
+++ b/lib/ldap
@@ -8,7 +8,7 @@
 # - install_ldap()
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_LDAP=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -166,7 +166,7 @@
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_LDAP
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/lvm b/lib/lvm
index 468a99a..ae6023a 100644
--- a/lib/lvm
+++ b/lib/lvm
@@ -16,7 +16,7 @@
 
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_LVM=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -182,7 +182,7 @@
 }
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_LVM
 
 # mode: shell-script
 # End:
diff --git a/lib/neutron-legacy b/lib/neutron-legacy
index 4e51425..6af44e6 100644
--- a/lib/neutron-legacy
+++ b/lib/neutron-legacy
@@ -112,6 +112,12 @@
 NEUTRON_CONF=$NEUTRON_CONF_DIR/neutron.conf
 export NEUTRON_TEST_CONFIG_FILE=${NEUTRON_TEST_CONFIG_FILE:-"$NEUTRON_CONF_DIR/debug.ini"}
 
+# Default provider for load balancer service
+DEFAULT_LB_PROVIDER=LOADBALANCER:Haproxy:neutron_lbaas.services.loadbalancer.drivers.haproxy.plugin_driver.HaproxyOnHostPluginDriver:default
+
+# Default provider for VPN service
+DEFAULT_VPN_PROVIDER=VPN:openswan:neutron_vpnaas.services.vpn.service_drivers.ipsec.IPsecVPNDriver:default
+
 # Agent binaries.  Note, binary paths for other agents are set in per-service
 # scripts in lib/neutron_plugins/services/
 AGENT_DHCP_BINARY="$NEUTRON_BIN_DIR/neutron-dhcp-agent"
@@ -144,8 +150,6 @@
 Q_ADMIN_USERNAME=${Q_ADMIN_USERNAME:-neutron}
 # Default auth strategy
 Q_AUTH_STRATEGY=${Q_AUTH_STRATEGY:-keystone}
-# Use namespace or not
-Q_USE_NAMESPACE=${Q_USE_NAMESPACE:-True}
 # RHEL's support for namespaces requires using veths with ovs
 Q_OVS_USE_VETH=${Q_OVS_USE_VETH:-False}
 Q_USE_ROOTWRAP=${Q_USE_ROOTWRAP:-True}
@@ -208,7 +212,7 @@
 # The plugin supports L3.
 Q_L3_ENABLED=${Q_L3_ENABLED:-False}
 # L3 routers exist per tenant
-Q_L3_ROUTER_PER_TENANT=${Q_L3_ROUTER_PER_TENANT:-False}
+Q_L3_ROUTER_PER_TENANT=${Q_L3_ROUTER_PER_TENANT:-True}
 
 # List of config file names in addition to the main plugin config file
 # See _configure_neutron_common() for details about setting it up
@@ -258,7 +262,7 @@
 
 # If using GRE tunnels for tenant networks, specify the range of
 # tunnel IDs from which tenant networks are allocated. Can be
-# overriden in ``localrc`` in necesssary.
+# overridden in ``localrc`` in necessary.
 TENANT_TUNNEL_RANGES=${TENANT_TUNNEL_RANGES:-1:1000}
 
 # To use VLANs for tenant networks, set to True in localrc. VLANs
@@ -359,7 +363,7 @@
 fi
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -488,7 +492,6 @@
     # optionally set options in nova_conf
     neutron_plugin_create_nova_conf
 
-    iniset $NOVA_CONF DEFAULT linuxnet_interface_driver "$LINUXNET_VIF_DRIVER"
     if is_service_enabled q-meta; then
         iniset $NOVA_CONF neutron service_metadata_proxy "True"
     fi
@@ -539,23 +542,25 @@
 
     if is_provider_network; then
         die_if_not_set $LINENO PHYSICAL_NETWORK "You must specify the PHYSICAL_NETWORK"
-        die_if_not_set $LINENO PROVIDER_NETWORK_TYPE "You must specifiy the PROVIDER_NETWORK_TYPE"
+        die_if_not_set $LINENO PROVIDER_NETWORK_TYPE "You must specify the PROVIDER_NETWORK_TYPE"
         NET_ID=$(neutron net-create $PHYSICAL_NETWORK --tenant_id $TENANT_ID --provider:network_type $PROVIDER_NETWORK_TYPE --provider:physical_network "$PHYSICAL_NETWORK" ${SEGMENTATION_ID:+--provider:segmentation_id $SEGMENTATION_ID} --shared | grep ' id ' | get_field 2)
         die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PHYSICAL_NETWORK $TENANT_ID"
 
         if [[ "$IP_VERSION" =~ 4.* ]]; then
-            SUBNET_ID=$(neutron subnet-create --tenant_id $TENANT_ID --ip_version 4 ${ALLOCATION_POOL:+--allocation-pool $ALLOCATION_POOL} --name $PROVIDER_SUBNET_NAME --gateway $NETWORK_GATEWAY $NET_ID $FIXED_RANGE | grep ' id ' | get_field 2)
+            SUBNET_ID=$(neutron subnet-create --tenant_id $TENANT_ID --ip_version 4 ${ALLOCATION_POOL:+--allocation-pool $ALLOCATION_POOL} --name $PROVIDER_SUBNET_NAME --gateway $NETWORK_GATEWAY --subnetpool None $NET_ID $FIXED_RANGE | grep ' id ' | get_field 2)
             die_if_not_set $LINENO SUBNET_ID "Failure creating SUBNET_ID for $PROVIDER_SUBNET_NAME $TENANT_ID"
         fi
 
         if [[ "$IP_VERSION" =~ .*6 ]]; then
-            SUBNET_V6_ID=$(neutron subnet-create --tenant_id $TENANT_ID --ip_version 6 --ipv6-address-mode slaac --gateway $V6_NETWORK_GATEWAY --name $PROVIDER_SUBNET_NAME_V6 $NET_ID $FIXED_RANGE_V6 | grep 'id' | get_field 2)
+            SUBNET_V6_ID=$(neutron subnet-create --tenant_id $TENANT_ID --ip_version 6 --ipv6-address-mode $IPV6_ADDRESS_MODE --gateway $V6_NETWORK_GATEWAY --name $PROVIDER_SUBNET_NAME_V6 --subnetpool_id None $NET_ID $FIXED_RANGE_V6 | grep 'id' | get_field 2)
             die_if_not_set $LINENO SUBNET_V6_ID "Failure creating SUBNET_V6_ID for $PROVIDER_SUBNET_NAME_V6 $TENANT_ID"
         fi
 
-        sudo ip link set $OVS_PHYSICAL_BRIDGE up
-        sudo ip link set br-int up
-        sudo ip link set $PUBLIC_INTERFACE up
+        if [[ $Q_AGENT == "openvswitch" ]]; then
+            sudo ip link set $OVS_PHYSICAL_BRIDGE up
+            sudo ip link set br-int up
+            sudo ip link set $PUBLIC_INTERFACE up
+        fi
     else
         NET_ID=$(neutron net-create --tenant-id $TENANT_ID "$PRIVATE_NETWORK_NAME" | grep ' id ' | get_field 2)
         die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PRIVATE_NETWORK_NAME $TENANT_ID"
@@ -641,7 +646,7 @@
         plugin_dir=$($ssh_dom0 "$xen_functions; set -eux; xapi_plugin_location")
 
         # install neutron plugins to dom0
-        tar -czf - -C $NEUTRON_DIR/neutron/plugins/openvswitch/agent/xenapi/etc/xapi.d/plugins/ ./ |
+        tar -czf - -C $NEUTRON_DIR/neutron/plugins/ml2/drivers/openvswitch/agent/xenapi/etc/xapi.d/plugins/ ./ |
             $ssh_dom0 "tar -xzf - -C $plugin_dir && chmod a+x $plugin_dir/*"
     fi
 }
@@ -701,7 +706,7 @@
 function start_neutron_l2_agent {
     run_process q-agt "$AGENT_BINARY --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE"
 
-    if is_provider_network; then
+    if is_provider_network && [[ $Q_AGENT == "openvswitch" ]]; then
         sudo ovs-vsctl --no-wait -- --may-exist add-port $OVS_PHYSICAL_BRIDGE $PUBLIC_INTERFACE
         sudo ip link set $OVS_PHYSICAL_BRIDGE up
         sudo ip link set br-int up
@@ -800,20 +805,15 @@
 
         local IP_ADD=""
         local IP_DEL=""
+        local IP_UP=""
         local DEFAULT_ROUTE_GW
-        DEFAULT_ROUTE_GW=$(ip r | awk "/default.+$from_intf/ { print \$3; exit }")
+        DEFAULT_ROUTE_GW=$(ip -f $af r | awk "/default.+$from_intf/ { print \$3; exit }")
         local ADD_OVS_PORT=""
 
-        if [[ $af == "inet" ]]; then
-            IP_BRD=$(ip -f $af a s dev $from_intf | grep inet | awk '{ print $2, $3, $4; exit }')
-        fi
-
-        if [[ $af == "inet6" ]]; then
-            IP_BRD=$(ip -f $af a s dev $from_intf | grep inet6 | awk '{ print $2, $3, $4; exit }')
-        fi
+        IP_BRD=$(ip -f $af a s dev $from_intf scope global primary | grep inet | awk '{ print $2, $3, $4; exit }')
 
         if [ "$DEFAULT_ROUTE_GW" != "" ]; then
-            ADD_DEFAULT_ROUTE="sudo ip r replace default via $DEFAULT_ROUTE_GW dev $to_intf"
+            ADD_DEFAULT_ROUTE="sudo ip -f $af r replace default via $DEFAULT_ROUTE_GW dev $to_intf"
         fi
 
         if [[ "$add_ovs_port" == "True" ]]; then
@@ -823,9 +823,10 @@
         if [[ "$IP_BRD" != "" ]]; then
             IP_DEL="sudo ip addr del $IP_BRD dev $from_intf"
             IP_ADD="sudo ip addr add $IP_BRD dev $to_intf"
+            IP_UP="sudo ip link set $to_intf up"
         fi
 
-        $IP_DEL; $IP_ADD; $ADD_OVS_PORT; $ADD_DEFAULT_ROUTE
+        $IP_DEL; $IP_ADD; $IP_UP; $ADD_OVS_PORT; $ADD_DEFAULT_ROUTE
     fi
 }
 
@@ -837,6 +838,10 @@
         _move_neutron_addresses_route "$OVS_PHYSICAL_BRIDGE" "$PUBLIC_INTERFACE" False "inet"
 
         if [[ $(ip -f inet6 a s dev "$OVS_PHYSICAL_BRIDGE" | grep -c 'global') != 0 ]]; then
+            # ip(8) wants the prefix length when deleting
+            local v6_gateway
+            v6_gateway=$(ip -6 a s dev $OVS_PHYSICAL_BRIDGE | grep $IPV6_PUBLIC_NETWORK_GATEWAY | awk '{ print $2 }')
+            sudo ip -6 addr del $v6_gateway dev $OVS_PHYSICAL_BRIDGE
             _move_neutron_addresses_route "$OVS_PHYSICAL_BRIDGE" "$PUBLIC_INTERFACE" False "inet6"
         fi
 
@@ -875,7 +880,10 @@
 function _configure_neutron_common {
     _create_neutron_conf_dir
 
-    cp $NEUTRON_DIR/etc/neutron.conf $NEUTRON_CONF
+    # Uses oslo config generator to generate core sample configuration files
+    (cd $NEUTRON_DIR && exec ./tools/generate_config_file_samples.sh)
+
+    cp $NEUTRON_DIR/etc/neutron.conf.sample $NEUTRON_CONF
 
     Q_POLICY_FILE=$NEUTRON_CONF_DIR/policy.json
     cp $NEUTRON_DIR/etc/policy.json $Q_POLICY_FILE
@@ -900,7 +908,9 @@
     Q_PLUGIN_CONF_FILE=$Q_PLUGIN_CONF_PATH/$Q_PLUGIN_CONF_FILENAME
     # NOTE(hichihara): Some neutron vendor plugins were already decomposed and
     # there is no config file in Neutron tree. They should prepare the file in each plugin.
-    if [ -f $NEUTRON_DIR/$Q_PLUGIN_CONF_FILE ]; then
+    if [ -f "$NEUTRON_DIR/$Q_PLUGIN_CONF_FILE.sample" ]; then
+        cp "$NEUTRON_DIR/$Q_PLUGIN_CONF_FILE.sample" /$Q_PLUGIN_CONF_FILE
+    elif [ -f $NEUTRON_DIR/$Q_PLUGIN_CONF_FILE ]; then
         cp $NEUTRON_DIR/$Q_PLUGIN_CONF_FILE /$Q_PLUGIN_CONF_FILE
     fi
 
@@ -908,6 +918,8 @@
     iniset $NEUTRON_CONF DEFAULT state_path $DATA_DIR/neutron
     iniset $NEUTRON_CONF DEFAULT use_syslog $SYSLOG
     iniset $NEUTRON_CONF DEFAULT bind_host $Q_LISTEN_ADDRESS
+    iniset $NEUTRON_CONF oslo_concurrency lock_path $DATA_DIR/neutron/lock
+
     # If addition config files are set, make sure their path name is set as well
     if [[ ${#Q_PLUGIN_EXTRA_CONF_FILES[@]} > 0 && $Q_PLUGIN_EXTRA_CONF_PATH == '' ]]; then
         die $LINENO "Neutron additional plugin config not set.. exiting"
@@ -964,11 +976,10 @@
         return
     fi
 
-    cp $NEUTRON_DIR/etc/l3_agent.ini $NEUTRON_TEST_CONFIG_FILE
+    cp $NEUTRON_DIR/etc/l3_agent.ini.sample $NEUTRON_TEST_CONFIG_FILE
 
     iniset $NEUTRON_TEST_CONFIG_FILE DEFAULT verbose False
     iniset $NEUTRON_TEST_CONFIG_FILE DEFAULT debug False
-    iniset $NEUTRON_TEST_CONFIG_FILE DEFAULT use_namespaces $Q_USE_NAMESPACE
     iniset $NEUTRON_TEST_CONFIG_FILE AGENT root_helper "$Q_RR_COMMAND"
     if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
         iniset $NEUTRON_TEST_CONFIG_FILE AGENT root_helper_daemon "$Q_RR_DAEMON_COMMAND"
@@ -981,11 +992,10 @@
 
 function _configure_neutron_dhcp_agent {
 
-    cp $NEUTRON_DIR/etc/dhcp_agent.ini $Q_DHCP_CONF_FILE
+    cp $NEUTRON_DIR/etc/dhcp_agent.ini.sample $Q_DHCP_CONF_FILE
 
     iniset $Q_DHCP_CONF_FILE DEFAULT verbose True
     iniset $Q_DHCP_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
-    iniset $Q_DHCP_CONF_FILE DEFAULT use_namespaces $Q_USE_NAMESPACE
     iniset $Q_DHCP_CONF_FILE AGENT root_helper "$Q_RR_COMMAND"
     if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
         iniset $Q_DHCP_CONF_FILE AGENT root_helper_daemon "$Q_RR_DAEMON_COMMAND"
@@ -1009,18 +1019,15 @@
 
 function _configure_neutron_l3_agent {
     Q_L3_ENABLED=True
-    # for l3-agent, only use per tenant router if we have namespaces
-    Q_L3_ROUTER_PER_TENANT=$Q_USE_NAMESPACE
 
     if is_service_enabled q-vpn; then
         neutron_vpn_configure_agent
     fi
 
-    cp $NEUTRON_DIR/etc/l3_agent.ini $Q_L3_CONF_FILE
+    cp $NEUTRON_DIR/etc/l3_agent.ini.sample $Q_L3_CONF_FILE
 
     iniset $Q_L3_CONF_FILE DEFAULT verbose True
     iniset $Q_L3_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
-    iniset $Q_L3_CONF_FILE DEFAULT use_namespaces $Q_USE_NAMESPACE
     iniset $Q_L3_CONF_FILE AGENT root_helper "$Q_RR_COMMAND"
     if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
         iniset $Q_L3_CONF_FILE AGENT root_helper_daemon "$Q_RR_DAEMON_COMMAND"
@@ -1038,7 +1045,7 @@
 }
 
 function _configure_neutron_metadata_agent {
-    cp $NEUTRON_DIR/etc/metadata_agent.ini $Q_META_CONF_FILE
+    cp $NEUTRON_DIR/etc/metadata_agent.ini.sample $Q_META_CONF_FILE
 
     iniset $Q_META_CONF_FILE DEFAULT verbose True
     iniset $Q_META_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
@@ -1059,8 +1066,12 @@
 }
 
 function _configure_neutron_lbaas {
-    if [ -f $NEUTRON_LBAAS_DIR/etc/neutron_lbaas.conf ]; then
-        cp $NEUTRON_LBAAS_DIR/etc/neutron_lbaas.conf $NEUTRON_CONF_DIR
+    # Uses oslo config generator to generate LBaaS sample configuration files
+    (cd $NEUTRON_LBAAS_DIR && exec ./tools/generate_config_file_samples.sh)
+
+    if [ -f $NEUTRON_LBAAS_DIR/etc/neutron_lbaas.conf.sample ]; then
+        cp $NEUTRON_LBAAS_DIR/etc/neutron_lbaas.conf.sample $NEUTRON_CONF_DIR/neutron_lbaas.conf
+        iniset $NEUTRON_CONF_DIR/neutron_lbaas.conf service_providers service_provider $DEFAULT_LB_PROVIDER
     fi
     neutron_agent_lbaas_configure_common
     neutron_agent_lbaas_configure_agent
@@ -1080,8 +1091,11 @@
 }
 
 function _configure_neutron_vpn {
-    if [ -f $NEUTRON_VPNAAS_DIR/etc/neutron_vpnaas.conf ]; then
-        cp $NEUTRON_VPNAAS_DIR/etc/neutron_vpnaas.conf $NEUTRON_CONF_DIR
+    # Uses oslo config generator to generate VPNaaS sample configuration files
+    (cd $NEUTRON_VPNAAS_DIR && exec ./tools/generate_config_file_samples.sh)
+    if [ -f $NEUTRON_VPNAAS_DIR/etc/neutron_vpnaas.conf.sample ]; then
+        cp $NEUTRON_VPNAAS_DIR/etc/neutron_vpnaas.conf.sample $NEUTRON_CONF_DIR/neutron_vpnaas.conf
+        iniset $NEUTRON_CONF_DIR/neutron_vpnaas.conf service_providers service_provider $DEFAULT_VPN_PROVIDER
     fi
     neutron_vpn_install_agent_packages
     neutron_vpn_configure_common
@@ -1130,7 +1144,7 @@
     iniset $NEUTRON_CONF DEFAULT auth_strategy $Q_AUTH_STRATEGY
     _neutron_setup_keystone $NEUTRON_CONF keystone_authtoken
 
-    # Configuration for neutron notifations to nova.
+    # Configuration for neutron notifications to nova.
     iniset $NEUTRON_CONF DEFAULT notify_nova_on_port_status_changes $Q_NOTIFY_NOVA_PORT_STATUS_CHANGES
     iniset $NEUTRON_CONF DEFAULT notify_nova_on_port_data_changes $Q_NOTIFY_NOVA_PORT_DATA_CHANGES
 
@@ -1243,6 +1257,7 @@
     subnet_params+="--ip_version 4 "
     subnet_params+="--gateway $NETWORK_GATEWAY "
     subnet_params+="--name $PRIVATE_SUBNET_NAME "
+    subnet_params+="--subnetpool None "
     subnet_params+="$NET_ID $FIXED_RANGE"
     local subnet_id
     subnet_id=$(neutron subnet-create $subnet_params | grep ' id ' | get_field 2)
@@ -1259,6 +1274,7 @@
     subnet_params+="--ip_version 6 "
     subnet_params+="--gateway $IPV6_PRIVATE_NETWORK_GATEWAY "
     subnet_params+="--name $IPV6_PRIVATE_SUBNET_NAME "
+    subnet_params+="--subnetpool None "
     subnet_params+="$NET_ID $FIXED_RANGE_V6 $ipv6_modes"
     local ipv6_subnet_id
     ipv6_subnet_id=$(neutron subnet-create $subnet_params | grep ' id ' | get_field 2)
@@ -1272,6 +1288,7 @@
     subnet_params+="${Q_FLOATING_ALLOCATION_POOL:+--allocation-pool $Q_FLOATING_ALLOCATION_POOL} "
     subnet_params+="--gateway $PUBLIC_NETWORK_GATEWAY "
     subnet_params+="--name $PUBLIC_SUBNET_NAME "
+    subnet_params+="--subnetpool None "
     subnet_params+="$EXT_NET_ID $FLOATING_RANGE "
     subnet_params+="-- --enable_dhcp=False"
     local id_and_ext_gw_ip
@@ -1285,6 +1302,7 @@
     local subnet_params="--ip_version 6 "
     subnet_params+="--gateway $IPV6_PUBLIC_NETWORK_GATEWAY "
     subnet_params+="--name $IPV6_PUBLIC_SUBNET_NAME "
+    subnet_params+="--subnetpool None "
     subnet_params+="$EXT_NET_ID $IPV6_PUBLIC_RANGE "
     subnet_params+="-- --enable_dhcp=False"
     local ipv6_id_and_ext_gw_ip
@@ -1309,7 +1327,7 @@
     if is_service_enabled q-l3; then
         # Configure and enable public bridge
         local ext_gw_interface="none"
-        if is_neutron_ovs_base_plugin && [[ "$Q_USE_NAMESPACE" = "True" ]]; then
+        if is_neutron_ovs_base_plugin; then
             ext_gw_interface=$(_neutron_get_ext_gw_interface)
         elif [[ "$Q_AGENT" = "linuxbridge" ]]; then
             # Search for the brq device the neutron router and network for $FIXED_RANGE
@@ -1325,7 +1343,7 @@
                 sudo ip addr add $ext_gw_ip/$cidr_len dev $ext_gw_interface
                 sudo ip link set $ext_gw_interface up
             fi
-            ROUTER_GW_IP=`neutron port-list -c fixed_ips -c device_owner | grep router_gateway | awk -F '"' -v subnet_id=$PUB_SUBNET_ID '$4 == subnet_id { print $8; }'`
+            ROUTER_GW_IP=`neutron port-list -c fixed_ips -c device_owner | grep router_gateway | awk -F'ip_address'  '{ print $2 }' | cut -f3 -d\" | tr '\n' ' '`
             die_if_not_set $LINENO ROUTER_GW_IP "Failure retrieving ROUTER_GW_IP"
             sudo ip route replace  $FIXED_RANGE via $ROUTER_GW_IP
         fi
@@ -1356,10 +1374,10 @@
         sudo sysctl -w net.ipv6.conf.all.forwarding=1
         # Configure and enable public bridge
         # Override global IPV6_ROUTER_GW_IP with the true value from neutron
-        IPV6_ROUTER_GW_IP=`neutron port-list -c fixed_ips | grep $ipv6_pub_subnet_id | awk -F '"' -v subnet_id=$ipv6_pub_subnet_id '$4 == subnet_id { print $8; }'`
+        IPV6_ROUTER_GW_IP=`neutron port-list -c fixed_ips | grep $ipv6_pub_subnet_id | awk -F'ip_address' '{ print $2 }' | cut -f3 -d\" | tr '\n' ' '`
         die_if_not_set $LINENO IPV6_ROUTER_GW_IP "Failure retrieving IPV6_ROUTER_GW_IP"
 
-        if is_neutron_ovs_base_plugin && [[ "$Q_USE_NAMESPACE" = "True" ]]; then
+        if is_neutron_ovs_base_plugin; then
             local ext_gw_interface
             ext_gw_interface=$(_neutron_get_ext_gw_interface)
             local ipv6_cidr_len=${IPV6_PUBLIC_RANGE#*/}
@@ -1374,7 +1392,7 @@
 
 # Explicitly set router id in l3 agent configuration
 function _neutron_set_router_id {
-    if [[ "$Q_USE_NAMESPACE" == "False" ]]; then
+    if [[ "$Q_L3_ROUTER_PER_TENANT" == "False" ]]; then
         iniset $Q_L3_CONF_FILE DEFAULT router_id $ROUTER_ID
     fi
 }
@@ -1498,7 +1516,7 @@
 
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_NEUTRON
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/neutron_plugins/bigswitch_floodlight b/lib/neutron_plugins/bigswitch_floodlight
index 4166131..586ded7 100644
--- a/lib/neutron_plugins/bigswitch_floodlight
+++ b/lib/neutron_plugins/bigswitch_floodlight
@@ -4,7 +4,7 @@
 # ------------------------------------
 
 # Save trace setting
-BS_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_BIGSWITCH=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/ovs_base
@@ -58,9 +58,9 @@
 function neutron_plugin_setup_interface_driver {
     local conf_file=$1
     if [ "$BS_FL_VIF_DRIVER" = "ivs" ]; then
-        iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.IVSInterfaceDriver
+        iniset $conf_file DEFAULT interface_driver ivs
     else
-        iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.OVSInterfaceDriver
+        iniset $conf_file DEFAULT interface_driver openvswitch
     fi
 }
 
@@ -75,4 +75,4 @@
 }
 
 # Restore xtrace
-$BS_XTRACE
+$_XTRACE_NEUTRON_BIGSWITCH
diff --git a/lib/neutron_plugins/brocade b/lib/neutron_plugins/brocade
index 557b94d..6ba0a66 100644
--- a/lib/neutron_plugins/brocade
+++ b/lib/neutron_plugins/brocade
@@ -4,7 +4,7 @@
 # ----------------------
 
 # Save trace setting
-BRCD_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_BROCADE=$(set +o | grep xtrace)
 set +o xtrace
 
 function is_neutron_ovs_base_plugin {
@@ -68,7 +68,7 @@
 
 function neutron_plugin_setup_interface_driver {
     local conf_file=$1
-    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.BridgeInterfaceDriver
+    iniset $conf_file DEFAULT interface_driver linuxbridge
 }
 
 function has_neutron_plugin_security_group {
@@ -81,4 +81,4 @@
 }
 
 # Restore xtrace
-$BRCD_XTRACE
+$_XTRACE_NEUTRON_BROCADE
diff --git a/lib/neutron_plugins/cisco b/lib/neutron_plugins/cisco
index 90dcd57..fc2cb8a 100644
--- a/lib/neutron_plugins/cisco
+++ b/lib/neutron_plugins/cisco
@@ -4,7 +4,7 @@
 # ---------------------------
 
 # Save trace setting
-CISCO_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_CISCO=$(set +o | grep xtrace)
 set +o xtrace
 
 # Scecify the VSM parameters
@@ -150,8 +150,8 @@
 
 function neutron_plugin_setup_interface_driver {
     local conf_file=$1
-    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.OVSInterfaceDriver
+    iniset $conf_file DEFAULT interface_driver openvswitch
 }
 
 # Restore xtrace
-$CISCO_XTRACE
+$_XTRACE_NEUTRON_CISCO
diff --git a/lib/neutron_plugins/embrane b/lib/neutron_plugins/embrane
index 2028496..385dab8 100644
--- a/lib/neutron_plugins/embrane
+++ b/lib/neutron_plugins/embrane
@@ -4,7 +4,7 @@
 # ---------------------------
 
 # Save trace setting
-EMBR_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_EMBR=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/openvswitch
@@ -39,4 +39,5 @@
 }
 
 # Restore xtrace
-$EMBR_XTRACE
+$_XTRACE_NEUTRON_EMBR
+
diff --git a/lib/neutron_plugins/ibm b/lib/neutron_plugins/ibm
deleted file mode 100644
index dd5cfa6..0000000
--- a/lib/neutron_plugins/ibm
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/bin/bash
-#
-# Neutron IBM SDN-VE plugin
-# ---------------------------
-
-# Save trace setting
-IBM_XTRACE=$(set +o | grep xtrace)
-set +o xtrace
-
-source $TOP_DIR/lib/neutron_plugins/ovs_base
-
-function neutron_plugin_install_agent_packages {
-    _neutron_ovs_base_install_agent_packages
-}
-
-function _neutron_interface_setup {
-    # Setup one interface on the integration bridge if needed
-    # The plugin agent to be used if more than one interface is used
-    local bridge=$1
-    local interface=$2
-    sudo ovs-vsctl --no-wait -- --may-exist add-port $bridge $interface
-}
-
-function neutron_setup_integration_bridge {
-    # Setup integration bridge if needed
-    if [[ "$SDNVE_INTEGRATION_BRIDGE" != "" ]]; then
-        neutron_ovs_base_cleanup
-        _neutron_ovs_base_setup_bridge $SDNVE_INTEGRATION_BRIDGE
-        if [[ "$SDNVE_INTERFACE_MAPPINGS" != "" ]]; then
-            interfaces=(${SDNVE_INTERFACE_MAPPINGS//[,:]/ })
-            _neutron_interface_setup $SDNVE_INTEGRATION_BRIDGE ${interfaces[1]}
-        fi
-    fi
-
-    # Set controller to SDNVE controller (1st of list) if exists
-    if [[ "$SDNVE_CONTROLLER_IPS" != "" ]]; then
-        # Get the first controller
-        controllers=(${SDNVE_CONTROLLER_IPS//[\[,\]]/ })
-        SDNVE_IP=${controllers[0]}
-        sudo ovs-vsctl set-controller $SDNVE_INTEGRATION_BRIDGE tcp:$SDNVE_IP
-    fi
-}
-
-function neutron_plugin_create_nova_conf {
-    # if n-cpu is enabled, then setup integration bridge
-    if is_service_enabled n-cpu; then
-        neutron_setup_integration_bridge
-    fi
-}
-
-function is_neutron_ovs_base_plugin {
-    if [[ "$SDNVE_INTEGRATION_BRIDGE" != "" ]]; then
-        # Yes, we use OVS.
-        return 0
-    else
-        # No, we do not use OVS.
-        return 1
-    fi
-}
-
-function neutron_plugin_configure_common {
-    Q_PLUGIN_CONF_PATH=etc/neutron/plugins/ibm
-    Q_PLUGIN_CONF_FILENAME=sdnve_neutron_plugin.ini
-    Q_PLUGIN_CLASS="neutron.plugins.ibm.sdnve_neutron_plugin.SdnvePluginV2"
-}
-
-function neutron_plugin_configure_service {
-    # Define extra "SDNVE" configuration options when q-svc is configured
-
-    iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.firewall.NoopFirewallDriver
-
-    if [[ "$SDNVE_CONTROLLER_IPS" != "" ]]; then
-        iniset /$Q_PLUGIN_CONF_FILE sdnve controller_ips $SDNVE_CONTROLLER_IPS
-    fi
-
-    if [[ "$SDNVE_INTEGRATION_BRIDGE" != "" ]]; then
-        iniset /$Q_PLUGIN_CONF_FILE sdnve integration_bridge $SDNVE_INTEGRATION_BRIDGE
-    fi
-
-    if [[ "$SDNVE_RESET_BRIDGE" != "" ]]; then
-        iniset /$Q_PLUGIN_CONF_FILE sdnve reset_bridge $SDNVE_RESET_BRIDGE
-    fi
-
-    if [[ "$SDNVE_OUT_OF_BAND" != "" ]]; then
-        iniset /$Q_PLUGIN_CONF_FILE sdnve out_of_band $SDNVE_OUT_OF_BAND
-    fi
-
-    if [[ "$SDNVE_INTERFACE_MAPPINGS" != "" ]]; then
-        iniset /$Q_PLUGIN_CONF_FILE sdnve interface_mappings $SDNVE_INTERFACE_MAPPINGS
-    fi
-
-    if [[ "$SDNVE_FAKE_CONTROLLER" != "" ]]; then
-        iniset /$Q_PLUGIN_CONF_FILE sdnve use_fake_controller $SDNVE_FAKE_CONTROLLER
-    fi
-
-
-    iniset $NEUTRON_CONF DEFAULT notification_driver neutron.openstack.common.notifier.no_op_notifier
-
-}
-
-function neutron_plugin_configure_plugin_agent {
-    AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-ibm-agent"
-}
-
-function neutron_plugin_configure_debug_command {
-    :
-}
-
-function neutron_plugin_setup_interface_driver {
-    return 0
-}
-
-function has_neutron_plugin_security_group {
-    # Does not support Security Groups
-    return 1
-}
-
-function neutron_ovs_base_cleanup {
-    if [[ "$SDNVE_RESET_BRIDGE" != False ]]; then
-        # remove all OVS ports that look like Neutron created ports
-        for port in $(sudo ovs-vsctl list port | grep -o -e tap[0-9a-f\-]* -e q[rg]-[0-9a-f\-]*); do
-            sudo ovs-vsctl del-port ${port}
-        done
-
-        # remove integration bridge created by Neutron
-        for bridge in $(sudo ovs-vsctl list-br | grep -o -e ${SDNVE_INTEGRATION_BRIDGE}); do
-            sudo ovs-vsctl del-br ${bridge}
-        done
-    fi
-}
-
-# Restore xtrace
-$IBM_XTRACE
diff --git a/lib/neutron_plugins/linuxbridge_agent b/lib/neutron_plugins/linuxbridge_agent
index bd4438d..096722b 100644
--- a/lib/neutron_plugins/linuxbridge_agent
+++ b/lib/neutron_plugins/linuxbridge_agent
@@ -4,7 +4,7 @@
 # -----------------------------
 
 # Save trace setting
-PLUGIN_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_LB=$(set +o | grep xtrace)
 set +o xtrace
 
 function neutron_lb_cleanup {
@@ -85,7 +85,7 @@
 
 function neutron_plugin_setup_interface_driver {
     local conf_file=$1
-    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.BridgeInterfaceDriver
+    iniset $conf_file DEFAULT interface_driver linuxbridge
 }
 
 function neutron_plugin_check_adv_test_requirements {
@@ -93,4 +93,4 @@
 }
 
 # Restore xtrace
-$PLUGIN_XTRACE
+$_XTRACE_NEUTRON_LB
diff --git a/lib/neutron_plugins/ml2 b/lib/neutron_plugins/ml2
index ace5335..30e1b03 100644
--- a/lib/neutron_plugins/ml2
+++ b/lib/neutron_plugins/ml2
@@ -4,7 +4,7 @@
 # ------------------------------
 
 # Save trace setting
-ML2_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_ML2=$(set +o | grep xtrace)
 set +o xtrace
 
 # Enable this to simply and quickly enable tunneling with ML2.
@@ -137,4 +137,4 @@
 }
 
 # Restore xtrace
-$ML2_XTRACE
+$_XTRACE_NEUTRON_ML2
diff --git a/lib/neutron_plugins/nuage b/lib/neutron_plugins/nuage
index 9e5307b..61e634e 100644
--- a/lib/neutron_plugins/nuage
+++ b/lib/neutron_plugins/nuage
@@ -4,7 +4,7 @@
 # ----------------------
 
 # Save trace setting
-NU_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_NU=$(set +o | grep xtrace)
 set +o xtrace
 
 function neutron_plugin_create_nova_conf {
@@ -66,4 +66,4 @@
 }
 
 # Restore xtrace
-$NU_XTRACE
+$_XTRACE_NEUTRON_NU
diff --git a/lib/neutron_plugins/openvswitch b/lib/neutron_plugins/openvswitch
index 891ab49..130eaac 100644
--- a/lib/neutron_plugins/openvswitch
+++ b/lib/neutron_plugins/openvswitch
@@ -7,7 +7,7 @@
 # which has been removed in Juno.
 
 # Save trace setting
-OVS_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_OVS=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/openvswitch_agent
@@ -56,4 +56,5 @@
 }
 
 # Restore xtrace
-$OVS_XTRACE
+$_XTRACE_NEUTRON_OVS
+
diff --git a/lib/neutron_plugins/openvswitch_agent b/lib/neutron_plugins/openvswitch_agent
index 48e47b3..b1acacd 100644
--- a/lib/neutron_plugins/openvswitch_agent
+++ b/lib/neutron_plugins/openvswitch_agent
@@ -4,7 +4,7 @@
 # -----------------------------
 
 # Save trace setting
-OVSA_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_OVSL2=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/neutron_plugins/ovs_base
@@ -71,6 +71,9 @@
         # Make a copy of our config for domU
         sudo cp /$Q_PLUGIN_CONF_FILE "/$Q_PLUGIN_CONF_FILE.domU"
 
+        # change domU's config file to STACK_USER
+        sudo chown $STACK_USER:$STACK_USER /$Q_PLUGIN_CONF_FILE.domU
+
         # Deal with Dom0's L2 Agent:
         Q_RR_DOM0_COMMAND="$NEUTRON_BIN_DIR/neutron-rootwrap-xen-dom0 $Q_RR_CONF_FILE"
 
@@ -82,7 +85,14 @@
         # Under XS/XCP, the ovs agent needs to target the dom0
         # integration bridge.  This is enabled by using a root wrapper
         # that executes commands on dom0 via a XenAPI plugin.
+        # XenAPI does not support daemon rootwrap now, so set root_helper_daemon empty
         iniset /$Q_PLUGIN_CONF_FILE agent root_helper "$Q_RR_DOM0_COMMAND"
+        iniset /$Q_PLUGIN_CONF_FILE agent root_helper_daemon ""
+
+        # Disable minimize polling, so that it can always detect OVS and Port changes
+        # This is a problem of xenserver + neutron, bug has been reported
+        # https://bugs.launchpad.net/neutron/+bug/1495423
+        iniset /$Q_PLUGIN_CONF_FILE agent minimize_polling False
 
         # Set "physical" mapping
         iniset /$Q_PLUGIN_CONF_FILE ovs bridge_mappings "physnet1:$FLAT_NETWORK_BRIDGE"
@@ -95,10 +105,14 @@
         # Create a bridge "br-$GUEST_INTERFACE_DEFAULT"
         _neutron_ovs_base_add_bridge "br-$GUEST_INTERFACE_DEFAULT"
         # Add $GUEST_INTERFACE_DEFAULT to that bridge
-        sudo ovs-vsctl add-port "br-$GUEST_INTERFACE_DEFAULT" $GUEST_INTERFACE_DEFAULT
+        sudo ovs-vsctl -- --may-exist add-port "br-$GUEST_INTERFACE_DEFAULT" $GUEST_INTERFACE_DEFAULT
+
+        # Create external bridge and add port
+        _neutron_ovs_base_add_bridge $PUBLIC_BRIDGE
+        sudo ovs-vsctl -- --may-exist add-port $PUBLIC_BRIDGE $PUBLIC_INTERFACE_DEFAULT
 
         # Set bridge mappings to "physnet1:br-$GUEST_INTERFACE_DEFAULT"
-        iniset "/$Q_PLUGIN_CONF_FILE.domU" ovs bridge_mappings "physnet1:br-$GUEST_INTERFACE_DEFAULT"
+        iniset "/$Q_PLUGIN_CONF_FILE.domU" ovs bridge_mappings "physnet1:br-$GUEST_INTERFACE_DEFAULT,physnet-ex:$PUBLIC_BRIDGE"
         # Set integration bridge to domU's
         iniset "/$Q_PLUGIN_CONF_FILE.domU" ovs integration_bridge $OVS_BRIDGE
         # Set root wrap
@@ -110,7 +124,7 @@
 
 function neutron_plugin_setup_interface_driver {
     local conf_file=$1
-    iniset $conf_file DEFAULT interface_driver neutron.agent.linux.interface.OVSInterfaceDriver
+    iniset $conf_file DEFAULT interface_driver openvswitch
 }
 
 function neutron_plugin_check_adv_test_requirements {
@@ -118,4 +132,4 @@
 }
 
 # Restore xtrace
-$OVSA_XTRACE
+$_XTRACE_NEUTRON_OVSL2
diff --git a/lib/neutron_plugins/ovs_base b/lib/neutron_plugins/ovs_base
index d3fd198..91aff33 100644
--- a/lib/neutron_plugins/ovs_base
+++ b/lib/neutron_plugins/ovs_base
@@ -4,7 +4,7 @@
 # -------------------------------------
 
 # Save trace setting
-OVSB_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_OVS_BASE=$(set +o | grep xtrace)
 set +o xtrace
 
 OVS_BRIDGE=${OVS_BRIDGE:-br-int}
@@ -114,4 +114,4 @@
 }
 
 # Restore xtrace
-$OVSB_XTRACE
+$_XTRACE_NEUTRON_OVS_BASE
diff --git a/lib/neutron_plugins/services/firewall b/lib/neutron_plugins/services/firewall
index 61a148e..2b7f32d 100644
--- a/lib/neutron_plugins/services/firewall
+++ b/lib/neutron_plugins/services/firewall
@@ -1,8 +1,10 @@
+#!/bin/bash
+
 # Neutron firewall plugin
 # ---------------------------
 
 # Save trace setting
-FW_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_FIREWALL=$(set +o | grep xtrace)
 set +o xtrace
 
 FWAAS_PLUGIN=neutron_fwaas.services.firewall.fwaas_plugin.FirewallPlugin
@@ -12,8 +14,11 @@
 }
 
 function neutron_fwaas_configure_driver {
+    # Uses oslo config generator to generate FWaaS sample configuration files
+    (cd $NEUTRON_FWAAS_DIR && exec ./tools/generate_config_file_samples.sh)
+
     FWAAS_DRIVER_CONF_FILENAME=/etc/neutron/fwaas_driver.ini
-    cp $NEUTRON_FWAAS_DIR/etc/fwaas_driver.ini $FWAAS_DRIVER_CONF_FILENAME
+    cp $NEUTRON_FWAAS_DIR/etc/fwaas_driver.ini.sample $FWAAS_DRIVER_CONF_FILENAME
 
     iniset_multiline $FWAAS_DRIVER_CONF_FILENAME fwaas enabled True
     iniset_multiline $FWAAS_DRIVER_CONF_FILENAME fwaas driver "neutron_fwaas.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver"
@@ -24,4 +29,4 @@
 }
 
 # Restore xtrace
-$FW_XTRACE
+$_XTRACE_NEUTRON_FIREWALL
diff --git a/lib/neutron_plugins/services/loadbalancer b/lib/neutron_plugins/services/loadbalancer
index 34190f9..30e9480 100644
--- a/lib/neutron_plugins/services/loadbalancer
+++ b/lib/neutron_plugins/services/loadbalancer
@@ -1,8 +1,10 @@
+#!/bin/bash
+
 # Neutron loadbalancer plugin
 # ---------------------------
 
 # Save trace setting
-LB_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_LB=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -26,7 +28,7 @@
 
     LBAAS_AGENT_CONF_FILENAME="$LBAAS_AGENT_CONF_PATH/lbaas_agent.ini"
 
-    cp $NEUTRON_LBAAS_DIR/etc/lbaas_agent.ini $LBAAS_AGENT_CONF_FILENAME
+    cp $NEUTRON_LBAAS_DIR/etc/lbaas_agent.ini.sample $LBAAS_AGENT_CONF_FILENAME
 
     # ovs_use_veth needs to be set before the plugin configuration
     # occurs to allow plugins to override the setting.
@@ -46,4 +48,4 @@
 }
 
 # Restore xtrace
-$LB_XTRACE
+$_XTRACE_NEUTRON_LB
diff --git a/lib/neutron_plugins/services/metering b/lib/neutron_plugins/services/metering
index 37ba019..5b32468 100644
--- a/lib/neutron_plugins/services/metering
+++ b/lib/neutron_plugins/services/metering
@@ -1,8 +1,10 @@
+#!/bin/bash
+
 # Neutron metering plugin
 # ---------------------------
 
 # Save trace setting
-METER_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NETURON_METER=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -19,7 +21,7 @@
 
     METERING_AGENT_CONF_FILENAME="$METERING_AGENT_CONF_PATH/metering_agent.ini"
 
-    cp $NEUTRON_DIR/etc/metering_agent.ini $METERING_AGENT_CONF_FILENAME
+    cp $NEUTRON_DIR/etc/metering_agent.ini.sample $METERING_AGENT_CONF_FILENAME
 }
 
 function neutron_metering_stop {
@@ -27,4 +29,5 @@
 }
 
 # Restore xtrace
-$METER_XTRACE
+$_XTRACE_NETURON_METER
+
diff --git a/lib/neutron_plugins/services/vpn b/lib/neutron_plugins/services/vpn
index 4d6a2bf..e790913 100644
--- a/lib/neutron_plugins/services/vpn
+++ b/lib/neutron_plugins/services/vpn
@@ -1,8 +1,10 @@
+#!/bin/bash
+
 # Neutron VPN plugin
 # ---------------------------
 
 # Save trace setting
-VPN_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_VPN=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -27,7 +29,9 @@
 }
 
 function neutron_vpn_configure_agent {
-    cp $NEUTRON_VPNAAS_DIR/etc/vpn_agent.ini $Q_VPN_CONF_FILE
+    # Uses oslo config generator to generate LBaaS sample configuration files
+    (cd $NEUTRON_VPNAAS_DIR && exec ./tools/generate_config_file_samples.sh)
+    cp $NEUTRON_VPNAAS_DIR/etc/vpn_agent.ini.sample $Q_VPN_CONF_FILE
     if [[ "$IPSEC_PACKAGE" == "strongswan" ]]; then
         iniset_multiline $Q_VPN_CONF_FILE vpnagent vpn_device_driver neutron_vpnaas.services.vpn.device_drivers.strongswan_ipsec.StrongSwanDriver
         if is_fedora; then
@@ -51,4 +55,4 @@
 }
 
 # Restore xtrace
-$VPN_XTRACE
+$_XTRACE_NEUTRON_VPN
diff --git a/lib/neutron_thirdparty/bigswitch_floodlight b/lib/neutron_thirdparty/bigswitch_floodlight
index e3f4689..45a4f2e 100644
--- a/lib/neutron_thirdparty/bigswitch_floodlight
+++ b/lib/neutron_thirdparty/bigswitch_floodlight
@@ -4,7 +4,7 @@
 # ------------------------------------------
 
 # Save trace setting
-BS3_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NEUTRON_BIGSWITCH=$(set +o | grep xtrace)
 set +o xtrace
 
 BS_FL_CONTROLLERS_PORT=${BS_FL_CONTROLLERS_PORT:-localhost:80}
@@ -51,4 +51,4 @@
 }
 
 # Restore xtrace
-$BS3_XTRACE
+$_XTRACE_NEUTRON_BIGSWITCH
diff --git a/lib/neutron_thirdparty/vmware_nsx b/lib/neutron_thirdparty/vmware_nsx
index 03853a9..e182fca 100644
--- a/lib/neutron_thirdparty/vmware_nsx
+++ b/lib/neutron_thirdparty/vmware_nsx
@@ -1,2 +1,4 @@
+#!/bin/bash
+
 # REVISIT(roeyc): this file left empty so that 'enable_service vmware_nsx'
 # continues to work.
diff --git a/lib/nova b/lib/nova
index 6e6075c..6337f87 100644
--- a/lib/nova
+++ b/lib/nova
@@ -7,6 +7,7 @@
 #
 # - ``functions`` file
 # - ``DEST``, ``DATA_DIR``, ``STACK_USER`` must be defined
+# - ``FILES``
 # - ``SERVICE_{TENANT_NAME|PASSWORD}`` must be defined
 # - ``LIBVIRT_TYPE`` must be defined
 # - ``INSTANCE_NAME_PREFIX``, ``VOLUME_NAME_PREFIX`` must be defined
@@ -24,7 +25,7 @@
 # - cleanup_nova
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_LIB_NOVA=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -87,6 +88,7 @@
 NOVA_SERVICE_LISTEN_ADDRESS=${NOVA_SERVICE_LISTEN_ADDRESS:-$SERVICE_LISTEN_ADDRESS}
 EC2_SERVICE_PORT=${EC2_SERVICE_PORT:-8773}
 EC2_SERVICE_PORT_INT=${EC2_SERVICE_PORT_INT:-18773}
+METADATA_SERVICE_PORT=${METADATA_SERVICE_PORT:-8775}
 
 # Option to enable/disable config drive
 # NOTE: Set ``FORCE_CONFIG_DRIVE="False"`` to turn OFF config drive
@@ -241,6 +243,7 @@
     sudo rm -f $NOVA_WSGI_DIR/*
     sudo rm -f $(apache_site_config_for nova-api)
     sudo rm -f $(apache_site_config_for nova-ec2-api)
+    sudo rm -f $(apache_site_config_for nova-metadata)
 }
 
 # _config_nova_apache_wsgi() - Set WSGI config files of Keystone
@@ -251,11 +254,14 @@
     nova_apache_conf=$(apache_site_config_for nova-api)
     local nova_ec2_apache_conf
     nova_ec2_apache_conf=$(apache_site_config_for nova-ec2-api)
+    local nova_metadata_apache_conf
+    nova_metadata_apache_conf=$(apache_site_config_for nova-metadata)
     local nova_ssl=""
     local nova_certfile=""
     local nova_keyfile=""
     local nova_api_port=$NOVA_SERVICE_PORT
     local nova_ec2_api_port=$EC2_SERVICE_PORT
+    local nova_metadata_port=$METADATA_SERVICE_PORT
     local venv_path=""
 
     if is_ssl_enabled_service nova-api; then
@@ -270,6 +276,7 @@
     # copy proxy vhost and wsgi helper files
     sudo cp $NOVA_DIR/nova/wsgi/nova-api.py $NOVA_WSGI_DIR/nova-api
     sudo cp $NOVA_DIR/nova/wsgi/nova-ec2-api.py $NOVA_WSGI_DIR/nova-ec2-api
+    sudo cp $NOVA_DIR/nova/wsgi/nova-metadata.py $NOVA_WSGI_DIR/nova-metadata
 
     sudo cp $FILES/apache-nova-api.template $nova_apache_conf
     sudo sed -e "
@@ -296,6 +303,19 @@
         s|%VIRTUALENV%|$venv_path|g
         s|%APIWORKERS%|$API_WORKERS|g
     " -i $nova_ec2_apache_conf
+
+    sudo cp $FILES/apache-nova-metadata.template $nova_metadata_apache_conf
+    sudo sed -e "
+        s|%PUBLICPORT%|$nova_metadata_port|g;
+        s|%APACHE_NAME%|$APACHE_NAME|g;
+        s|%PUBLICWSGI%|$NOVA_WSGI_DIR/nova-metadata|g;
+        s|%SSLENGINE%|$nova_ssl|g;
+        s|%SSLCERTFILE%|$nova_certfile|g;
+        s|%SSLKEYFILE%|$nova_keyfile|g;
+        s|%USER%|$STACK_USER|g;
+        s|%VIRTUALENV%|$venv_path|g
+        s|%APIWORKERS%|$API_WORKERS|g
+    " -i $nova_metadata_apache_conf
 }
 
 # configure_nova() - Set config files, create data dirs, etc
@@ -444,13 +464,18 @@
 
         # EC2
         if [[ "$KEYSTONE_CATALOG_BACKEND" = "sql" ]]; then
-
+            local nova_ec2_api_url
+            if [[ "$NOVA_USE_MOD_WSGI" == "False" ]]; then
+                nova_ec2_api_url="$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:$EC2_SERVICE_PORT/"
+            else
+                nova_ec2_api_url="$EC2_SERVICE_PROTOCOL://$SERVICE_HOST/ec2"
+            fi
             get_or_create_service "ec2" "ec2" "EC2 Compatibility Layer"
             get_or_create_endpoint "ec2" \
                 "$REGION_NAME" \
-                "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/" \
-                "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/" \
-                "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/"
+                "$nova_ec2_api_url" \
+                "$nova_ec2_api_url" \
+                "$nova_ec2_api_url"
         fi
     fi
 
@@ -475,7 +500,6 @@
 
     # (Re)create ``nova.conf``
     rm -f $NOVA_CONF
-    iniset $NOVA_CONF DEFAULT verbose "True"
     iniset $NOVA_CONF DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL"
     if [ "$NOVA_ALLOW_MOVE_TO_SAME_HOST" == "True" ]; then
         iniset $NOVA_CONF DEFAULT allow_resize_to_same_host "True"
@@ -644,6 +668,7 @@
         iniset $NOVA_CONF serial_console serialproxy_host "$NOVA_SERVICE_LISTEN_ADDRESS"
         iniset $NOVA_CONF serial_console enabled True
     fi
+    iniset $NOVA_CONF DEFAULT graceful_shutdown_timeout "$SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT"
 }
 
 function init_nova_cells {
@@ -793,9 +818,11 @@
     if [ -f ${enabled_site_file} ] && [ "$NOVA_USE_MOD_WSGI" == "True" ]; then
         enable_apache_site nova-api
         enable_apache_site nova-ec2-api
+        enable_apache_site nova-metadata
         restart_apache_server
         tail_log nova-api /var/log/$APACHE_NAME/nova-api.log
         tail_log nova-ec2-api /var/log/$APACHE_NAME/nova-ec2-api.log
+        tail_log nova-metadata /var/log/$APACHE_NAME/nova-metadata.log
     else
         run_process n-api "$NOVA_BIN_DIR/nova-api"
     fi
@@ -911,6 +938,7 @@
     if [ "$NOVA_USE_MOD_WSGI" == "True" ]; then
         disable_apache_site nova-api
         disable_apache_site nova-ec2-api
+        disable_apache_site nova-metadata
         restart_apache_server
     else
         stop_process n-api
@@ -931,7 +959,7 @@
 
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_LIB_NOVA
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/nova_plugins/functions-libvirt b/lib/nova_plugins/functions-libvirt
index 5525cfd..dae55c6 100644
--- a/lib/nova_plugins/functions-libvirt
+++ b/lib/nova_plugins/functions-libvirt
@@ -8,7 +8,7 @@
 # ``STACK_USER`` has to be defined
 
 # Save trace setting
-LV_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NOVA_FN_LIBVIRT=$(set +o | grep xtrace)
 set +o xtrace
 
 # Defaults
@@ -23,7 +23,7 @@
 # Installs required distro-specific libvirt packages.
 function install_libvirt {
     if is_ubuntu; then
-        if is_arch "aarch64" && [[ ${DISTRO} =~ (trusty|utopic) ]]; then
+        if is_arch "aarch64" && [[ ${DISTRO} == "trusty" ]]; then
             install_package qemu-system
         else
             install_package qemu-kvm
@@ -31,6 +31,11 @@
         fi
         install_package libvirt-bin libvirt-dev
         pip_install_gr libvirt-python
+        if [[ "$EBTABLES_RACE_FIX" == "True" ]]; then
+            # Work around for bug #1501558. We can remove this once we
+            # get to a version of Ubuntu that has new enough libvirt.
+            TOP_DIR=$TOP_DIR $TOP_DIR/tools/install_ebtables_workaround.sh
+        fi
         #pip_install_gr <there-si-no-guestfs-in-pypi>
     elif is_fedora || is_suse; then
         install_package kvm
@@ -129,7 +134,7 @@
 
 
 # Restore xtrace
-$LV_XTRACE
+$_XTRACE_NOVA_FN_LIBVIRT
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/nova_plugins/hypervisor-fake b/lib/nova_plugins/hypervisor-fake
index 3180d91..2434dce 100644
--- a/lib/nova_plugins/hypervisor-fake
+++ b/lib/nova_plugins/hypervisor-fake
@@ -17,7 +17,7 @@
 # cleanup_nova_hypervisor - remove transient data and cache
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_VIRTFAKE=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -72,7 +72,7 @@
 
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_VIRTFAKE
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/nova_plugins/hypervisor-ironic b/lib/nova_plugins/hypervisor-ironic
index b9e286d..c6ed85d 100644
--- a/lib/nova_plugins/hypervisor-ironic
+++ b/lib/nova_plugins/hypervisor-ironic
@@ -17,7 +17,7 @@
 # cleanup_nova_hypervisor - remove transient data and cache
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_HYP_IRONIC=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/nova_plugins/functions-libvirt
@@ -81,7 +81,7 @@
 
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_HYP_IRONIC
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/nova_plugins/hypervisor-libvirt b/lib/nova_plugins/hypervisor-libvirt
index c54a716..8bbaa21 100644
--- a/lib/nova_plugins/hypervisor-libvirt
+++ b/lib/nova_plugins/hypervisor-libvirt
@@ -17,7 +17,7 @@
 # cleanup_nova_hypervisor - remove transient data and cache
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NOVA_LIBVIRT=$(set +o | grep xtrace)
 set +o xtrace
 
 source $TOP_DIR/lib/nova_plugins/functions-libvirt
@@ -105,7 +105,7 @@
 
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_NOVA_LIBVIRT
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/nova_plugins/hypervisor-openvz b/lib/nova_plugins/hypervisor-openvz
index cce36b8..58ab5c1 100644
--- a/lib/nova_plugins/hypervisor-openvz
+++ b/lib/nova_plugins/hypervisor-openvz
@@ -17,7 +17,7 @@
 # cleanup_nova_hypervisor - remove transient data and cache
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_OPENVZ=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -62,7 +62,7 @@
 
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_OPENVZ
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/nova_plugins/hypervisor-vsphere b/lib/nova_plugins/hypervisor-vsphere
index 698f836..7c08bc9 100644
--- a/lib/nova_plugins/hypervisor-vsphere
+++ b/lib/nova_plugins/hypervisor-vsphere
@@ -17,7 +17,7 @@
 # cleanup_nova_hypervisor - remove transient data and cache
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_NOVA_VSPHERE=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -64,7 +64,7 @@
 
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_NOVA_VSPHERE
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/nova_plugins/hypervisor-xenserver b/lib/nova_plugins/hypervisor-xenserver
index efce383..3eb9149 100644
--- a/lib/nova_plugins/hypervisor-xenserver
+++ b/lib/nova_plugins/hypervisor-xenserver
@@ -17,7 +17,7 @@
 # cleanup_nova_hypervisor - remove transient data and cache
 
 # Save trace setting
-MY_XTRACE=$(set +o | grep xtrace)
+_XTRACE_XENSERVER=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -79,7 +79,7 @@
 
     # Create a cron job that will rotate guest logs
     $ssh_dom0 crontab - << CRONTAB
-* * * * * /root/rotate_xen_guest_logs.sh
+* * * * * /root/rotate_xen_guest_logs.sh >/dev/null 2>&1
 CRONTAB
 
     # Create directories for kernels and images
@@ -111,7 +111,7 @@
 
 
 # Restore xtrace
-$MY_XTRACE
+$_XTRACE_XENSERVER
 
 # Local variables:
 # mode: shell-script
diff --git a/lib/oslo b/lib/oslo
index f64f327..3d6fbb3 100644
--- a/lib/oslo
+++ b/lib/oslo
@@ -16,7 +16,7 @@
 # - install_oslo
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_LIB_OSLO=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -36,6 +36,7 @@
 GITDIR["oslo.messaging"]=$DEST/oslo.messaging
 GITDIR["oslo.middleware"]=$DEST/oslo.middleware
 GITDIR["oslo.policy"]=$DEST/oslo.policy
+GITDIR["oslo.privsep"]=$DEST/oslo.privsep
 GITDIR["oslo.reports"]=$DEST/oslo.reports
 GITDIR["oslo.rootwrap"]=$DEST/oslo.rootwrap
 GITDIR["oslo.serialization"]=$DEST/oslo.serialization
@@ -79,6 +80,7 @@
     _do_install_oslo_lib "oslo.messaging"
     _do_install_oslo_lib "oslo.middleware"
     _do_install_oslo_lib "oslo.policy"
+    _do_install_oslo_lib "oslo.privsep"
     _do_install_oslo_lib "oslo.reports"
     _do_install_oslo_lib "oslo.rootwrap"
     _do_install_oslo_lib "oslo.serialization"
@@ -93,7 +95,7 @@
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_LIB_OSLO
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/rpc_backend b/lib/rpc_backend
index 03eacd8..3864ade 100644
--- a/lib/rpc_backend
+++ b/lib/rpc_backend
@@ -21,7 +21,7 @@
 # of this file which is a standard interface.
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_RPC_BACKEND=$(set +o | grep xtrace)
 set +o xtrace
 
 # Functions
@@ -58,7 +58,7 @@
         # NOTE(bnemec): Retry initial rabbitmq configuration to deal with
         # the fact that sometimes it fails to start properly.
         # Reference: https://bugzilla.redhat.com/show_bug.cgi?id=1144100
-        # NOTE(tonyb): Extend the orginal retry logic to only restart rabbitmq
+        # NOTE(tonyb): Extend the original retry logic to only restart rabbitmq
         # every second time around the loop.
         # See: https://bugs.launchpad.net/devstack/+bug/1449056 for details on
         # why this is needed.  This can bee seen on vivid and Debian unstable
@@ -106,7 +106,7 @@
     fi
 }
 
-# iniset cofiguration
+# iniset configuration
 function iniset_rpc_backend {
     local package=$1
     local file=$2
@@ -141,7 +141,7 @@
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_RPC_BACKEND
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/stack b/lib/stack
index 47e8ce2..f09ddce 100644
--- a/lib/stack
+++ b/lib/stack
@@ -14,11 +14,12 @@
 # Functions
 # ---------
 
-# Generic service install handles venv creation if confgured for service
+# Generic service install handles venv creation if configured for service
 # stack_install_service service
 function stack_install_service {
     local service=$1
     if type install_${service} >/dev/null 2>&1; then
+        # FIXME(dhellmann): Needs to be python3-aware at some point.
         if [[ ${USE_VENV} = True && -n ${PROJECT_VENV[$service]:-} ]]; then
             rm -rf ${PROJECT_VENV[$service]}
             source $TOP_DIR/tools/build_venv.sh ${PROJECT_VENV[$service]} ${ADDITIONAL_VENV_PACKAGES//,/ }
diff --git a/lib/swift b/lib/swift
index 27832dc..b596142 100644
--- a/lib/swift
+++ b/lib/swift
@@ -24,7 +24,7 @@
 # - _cleanup_swift_apache_wsgi
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_LIB_SWIFT=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -44,6 +44,7 @@
 SWIFT3_DIR=$DEST/swift3
 
 SWIFT_SERVICE_PROTOCOL=${SWIFT_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
+SWIFT_DEFAULT_BIND_PORT=${SWIFT_DEFAULT_BIND_PORT:-8080}
 SWIFT_DEFAULT_BIND_PORT_INT=${SWIFT_DEFAULT_BIND_PORT_INT:-8081}
 SWIFT_SERVICE_LOCAL_HOST=${SWIFT_SERVICE_LOCAL_HOST:-$SERVICE_LOCAL_HOST}
 SWIFT_SERVICE_LISTEN_ADDRESS=${SWIFT_SERVICE_LISTEN_ADDRESS:-$SERVICE_LISTEN_ADDRESS}
@@ -62,7 +63,7 @@
 if is_service_enabled s-proxy && is_service_enabled swift3; then
     # If we are using ``swift3``, we can default the S3 port to swift instead
     # of nova-objectstore
-    S3_SERVICE_PORT=${S3_SERVICE_PORT:-8080}
+    S3_SERVICE_PORT=${S3_SERVICE_PORT:-$SWIFT_DEFAULT_BIND_PORT}
 fi
 
 if is_service_enabled g-api; then
@@ -122,13 +123,13 @@
 # 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
+# Set ``SWIFT_MAX_HEADER_SIZE`` to configure the maximum 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
+# Port bases used in port number calculation for the service "nodes"
+# The specified port number will be used, the additional ports calculated by
 # base_port + node_num * 10
 OBJECT_PORT_BASE=${OBJECT_PORT_BASE:-6613}
 CONTAINER_PORT_BASE=${CONTAINER_PORT_BASE:-6611}
@@ -183,7 +184,7 @@
 # _config_swift_apache_wsgi() - Set WSGI config files of Swift
 function _config_swift_apache_wsgi {
     sudo mkdir -p ${SWIFT_APACHE_WSGI_DIR}
-    local proxy_port=${SWIFT_DEFAULT_BIND_PORT:-8080}
+    local proxy_port=${SWIFT_DEFAULT_BIND_PORT}
 
     # copy proxy vhost and wsgi file
     sudo cp ${SWIFT_DIR}/examples/apache2/proxy-server.template $(apache_site_config_for proxy-server)
@@ -347,7 +348,7 @@
     local csyncfile=${SWIFT_CONF_DIR}/container-sync-realms.conf
     cp ${SWIFT_DIR}/etc/container-sync-realms.conf-sample ${csyncfile}
     iniset ${csyncfile} realm1 key realm1key
-    iniset ${csyncfile} realm1 cluster_name1 "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:8080/v1/"
+    iniset ${csyncfile} realm1 cluster_name1 "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:$SWIFT_DEFAULT_BIND_PORT/v1/"
 
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT user
     iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT user ${STACK_USER}
@@ -368,7 +369,7 @@
     if is_service_enabled tls-proxy; then
         iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port ${SWIFT_DEFAULT_BIND_PORT_INT}
     else
-        iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port ${SWIFT_DEFAULT_BIND_PORT:-8080}
+        iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port ${SWIFT_DEFAULT_BIND_PORT}
     fi
 
     if is_ssl_enabled_service s-proxy; then
@@ -625,9 +626,9 @@
         get_or_create_service "swift" "object-store" "Swift Service"
         get_or_create_endpoint "object-store" \
             "$REGION_NAME" \
-            "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:8080/v1/AUTH_\$(tenant_id)s" \
-            "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:8080" \
-            "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:8080/v1/AUTH_\$(tenant_id)s"
+            "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:$SWIFT_DEFAULT_BIND_PORT/v1/AUTH_\$(tenant_id)s" \
+            "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:$SWIFT_DEFAULT_BIND_PORT" \
+            "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:$SWIFT_DEFAULT_BIND_PORT/v1/AUTH_\$(tenant_id)s"
     fi
 
     local swift_tenant_test1
@@ -775,7 +776,7 @@
         swift-init --run-dir=${SWIFT_DATA_DIR}/run ${type} stop || true
     done
     if is_service_enabled tls-proxy; then
-        local proxy_port=${SWIFT_DEFAULT_BIND_PORT:-8080}
+        local proxy_port=${SWIFT_DEFAULT_BIND_PORT}
         start_tls_proxy '*' $proxy_port $SERVICE_HOST $SWIFT_DEFAULT_BIND_PORT_INT &
     fi
     run_process s-proxy "$SWIFT_DIR/bin/swift-proxy-server ${SWIFT_CONF_DIR}/proxy-server.conf -v"
@@ -812,15 +813,17 @@
 }
 
 function swift_configure_tempurls {
+    # note we are using swift credentials!
     OS_USERNAME=swift \
-        OS_PROJECT_NAME=$SERVICE_TENANT_NAME \
-        OS_PASSWORD=$SERVICE_PASSWORD \
-        OS_AUTH_URL=$SERVICE_ENDPOINT \
-        swift post --auth-version 3 -m "Temp-URL-Key: $SWIFT_TEMPURL_KEY"
+    OS_PASSWORD=$SERVICE_PASSWORD \
+    OS_PROJECT_NAME=$SERVICE_TENANT_NAME \
+    OS_AUTH_URL=$SERVICE_ENDPOINT \
+    openstack object store account \
+        set --property "Temp-URL-Key=$SWIFT_TEMPURL_KEY"
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_LIB_SWIFT
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/tempest b/lib/tempest
index 10dd652..ecc4865 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -15,7 +15,6 @@
 #   - ``SERVICE_HOST``
 #   - ``BASE_SQL_CONN`` ``lib/database`` declares
 #   - ``PUBLIC_NETWORK_NAME``
-#   - ``Q_USE_NAMESPACE``
 #   - ``Q_ROUTER_NAME``
 #   - ``Q_L3_ENABLED``
 #   - ``VIRT_DRIVER``
@@ -24,7 +23,7 @@
 #
 # Optional Dependencies:
 #
-# - ``ALT_*`` (similar vars exists in keystone_data.sh)
+# - ``ALT_*``
 # - ``LIVE_MIGRATION_AVAILABLE``
 # - ``USE_BLOCK_MIGRATION_FOR_LIVE_MIGRATION``
 # - ``DEFAULT_INSTANCE_TYPE``
@@ -39,7 +38,7 @@
 # - init_tempest
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_TEMPEST=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -132,7 +131,6 @@
     local flavor_lines
     local public_network_id
     local public_router_id
-    local tenant_networks_reachable
     local boto_instance_type="m1.tiny"
     local ssh_connect_method="fixed"
 
@@ -198,8 +196,8 @@
     if is_service_enabled nova; then
         # If ``DEFAULT_INSTANCE_TYPE`` is not declared, use the new behavior
         # Tempest creates its own instance types
+        available_flavors=$(nova flavor-list)
         if  [[ -z "$DEFAULT_INSTANCE_TYPE" ]]; then
-            available_flavors=$(nova flavor-list)
             if [[ ! ( $available_flavors =~ 'm1.nano' ) ]]; then
                 nova flavor-create m1.nano 42 64 0 1
             fi
@@ -212,15 +210,14 @@
         else
             # Check Nova for existing flavors, if ``DEFAULT_INSTANCE_TYPE`` is set use it.
             boto_instance_type=$DEFAULT_INSTANCE_TYPE
-            flavor_lines=`nova flavor-list`
             IFS=$'\r\n'
             flavors=""
-            for line in $flavor_lines; do
+            for line in $available_flavors; do
                 f=$(echo $line | awk "/ $DEFAULT_INSTANCE_TYPE / { print \$2 }")
                 flavors="$flavors $f"
             done
 
-            for line in $flavor_lines; do
+            for line in $available_flavors; do
                 flavors="$flavors `echo $line | grep -v "^\(|\s*ID\|+--\)" | cut -d' ' -f2`"
             done
 
@@ -246,13 +243,8 @@
         fi
     fi
 
-    if [ "$Q_USE_NAMESPACE" != "False" ]; then
-        tenant_networks_reachable=false
-        if ! is_service_enabled n-net; then
-            ssh_connect_method="floating"
-        fi
-    else
-        tenant_networks_reachable=true
+    if ! is_service_enabled n-net; then
+        ssh_connect_method="floating"
     fi
 
     ssh_connect_method=${TEMPEST_SSH_CONNECT_METHOD:-$ssh_connect_method}
@@ -260,12 +252,6 @@
     if [ "$Q_L3_ENABLED" = "True" ]; then
         public_network_id=$(neutron net-list | grep $PUBLIC_NETWORK_NAME | \
             awk '{print $2}')
-        if [ "$Q_USE_NAMESPACE" == "False" ]; then
-            # If namespaces are disabled, DevStack will create a single
-            # public router that tempest should be configured to use.
-            public_router_id=$(neutron router-list | awk "/ $Q_ROUTER_NAME / \
-                { print \$2 }")
-        fi
     fi
 
     EC2_URL=$(get_endpoint_url ec2 public || true)
@@ -343,6 +329,9 @@
     iniset $TEMPEST_CONFIG compute flavor_ref $flavor_ref
     iniset $TEMPEST_CONFIG compute flavor_ref_alt $flavor_ref_alt
     iniset $TEMPEST_CONFIG compute ssh_connect_method $ssh_connect_method
+    # set the equiv validation option here as well to ensure they are
+    # in sync. They shouldn't be separate options.
+    iniset $TEMPEST_CONFIG validation connect_method $ssh_connect_method
     if [[ ! $(is_service_enabled n-cell) && ! $(is_service_enabled neutron) ]]; then
         iniset $TEMPEST_CONFIG compute fixed_network_name $PRIVATE_NETWORK_NAME
     fi
@@ -371,6 +360,30 @@
         compute_api_extensions=$(remove_disabled_extensions $compute_api_extensions $DISABLE_COMPUTE_API_EXTENSIONS)
     fi
 
+    # Set the microversion range for compute tests.
+    # This is used to run the Nova microversions tests.
+    # Setting [None, latest] range of microversion which allow Tempest to run all microversions tests.
+    # NOTE- To avoid microversion tests failure on stable branch, we need to change "tempest_compute_max_microversion"
+    #       for stable branch on each release which should be changed from "latest" to max supported version of that release.
+    local tempest_compute_min_microversion=${TEMPEST_COMPUTE_MIN_MICROVERSION:-None}
+    local tempest_compute_max_microversion=${TEMPEST_COMPUTE_MAX_MICROVERSION:-"latest"}
+    # Reset microversions to None where v2.0 is running which does not support microversion.
+    # Both "None" means no microversion testing.
+    if [[ "$TEMPEST_COMPUTE_TYPE" == "compute_legacy" ]]; then
+        tempest_compute_min_microversion=None
+        tempest_compute_max_microversion=None
+    fi
+    if [ "$tempest_compute_min_microversion" == "None" ]; then
+        inicomment $TEMPEST_CONFIG compute-feature-enabled min_microversion
+    else
+        iniset $TEMPEST_CONFIG compute-feature-enabled min_microversion $tempest_compute_min_microversion
+    fi
+    if [ "$tempest_compute_max_microversion" == "None" ]; then
+        inicomment $TEMPEST_CONFIG compute-feature-enabled max_microversion
+    else
+        iniset $TEMPEST_CONFIG compute-feature-enabled max_microversion $tempest_compute_max_microversion
+    fi
+
     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
@@ -390,11 +403,20 @@
         iniset $TEMPEST_CONFIG compute-feature-enabled shelve False
         # Cells doesn't support hot-plugging virtual interfaces.
         iniset $TEMPEST_CONFIG compute-feature-enabled interface_attach False
+
+        if  [[ -z "$DEFAULT_INSTANCE_TYPE" ]]; then
+            # Cells supports resize but does not currently work with devstack
+            # because of the custom flavors created for Tempest runs which are
+            # not in the cells database.
+            # TODO(mriedem): work on adding a nova-manage command to sync
+            # flavors into the cells database.
+            iniset $TEMPEST_CONFIG compute-feature-enabled resize False
+        fi
     fi
 
     # Network
     iniset $TEMPEST_CONFIG network api_version 2.0
-    iniset $TEMPEST_CONFIG network tenant_networks_reachable "$tenant_networks_reachable"
+    iniset $TEMPEST_CONFIG network tenant_networks_reachable false
     iniset $TEMPEST_CONFIG network public_network_id "$public_network_id"
     iniset $TEMPEST_CONFIG network public_router_id "$public_router_id"
     iniset $TEMPEST_CONFIG network default_network "$FIXED_RANGE"
@@ -467,6 +489,8 @@
     iniset $TEMPEST_CONFIG volume-feature-enabled bootable True
     # TODO(jordanP): Remove the extend_with_snapshot flag when Juno is end of life.
     iniset $TEMPEST_CONFIG volume-feature-enabled extend_with_snapshot True
+    # TODO(obutenko): Remove the incremental_backup_force flag when Kilo and Juno is end of life.
+    iniset $TEMPEST_CONFIG volume-feature-enabled incremental_backup_force True
 
     local volume_api_extensions=${VOLUME_API_EXTENSIONS:-"all"}
     if [[ ! -z "$DISABLE_VOLUME_API_EXTENSIONS" ]]; then
@@ -512,7 +536,8 @@
     # Baremetal
     if [ "$VIRT_DRIVER" = "ironic" ] ; then
         iniset $TEMPEST_CONFIG baremetal driver_enabled True
-        iniset $TEMPEST_CONFIG baremetal unprovision_timeout 300
+        iniset $TEMPEST_CONFIG baremetal unprovision_timeout $BUILD_TIMEOUT
+        iniset $TEMPEST_CONFIG baremetal active_timeout $BUILD_TIMEOUT
         iniset $TEMPEST_CONFIG baremetal deploy_img_dir $FILES
         iniset $TEMPEST_CONFIG baremetal node_uuid $IRONIC_NODE_UUID
         iniset $TEMPEST_CONFIG compute-feature-enabled change_password False
@@ -531,6 +556,8 @@
     if [ "$VIRT_DRIVER" = "libvirt" ] && [ "$LIBVIRT_TYPE" = "lxc" ]; then
         iniset $TEMPEST_CONFIG compute-feature-enabled rescue False
         iniset $TEMPEST_CONFIG compute-feature-enabled resize False
+        iniset $TEMPEST_CONFIG compute-feature-enabled shelve False
+        iniset $TEMPEST_CONFIG compute-feature-enabled snapshot False
         iniset $TEMPEST_CONFIG compute-feature-enabled suspend False
     fi
 
@@ -548,6 +575,12 @@
         fi
     done
 
+    if [ "$VIRT_DRIVER" = "libvirt" ] && [ "$LIBVIRT_TYPE" = "lxc" ]; then
+        # libvirt-lxc does not support boot from volume or attaching volumes
+        # so basically anything with cinder is out of the question.
+        iniset $TEMPEST_CONFIG service_available cinder "False"
+    fi
+
     if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
         # Use the ``BOTO_CONFIG`` environment variable to point to this file
         iniset -sudo $BOTO_CONF Boto ca_certificates_file $SSL_BUNDLE_FILE
@@ -564,9 +597,13 @@
         fi
         iniset $TEMPEST_CONFIG auth allow_tenant_isolation False
         iniset $TEMPEST_CONFIG auth test_accounts_file "etc/accounts.yaml"
+    elif [[ $TEMPEST_HAS_ADMIN == "False" ]]; then
+        iniset $TEMPEST_CONFIG auth allow_tenant_isolation ${TEMPEST_ALLOW_TENANT_ISOLATION:-False}
+
     else
         iniset $TEMPEST_CONFIG auth allow_tenant_isolation ${TEMPEST_ALLOW_TENANT_ISOLATION:-True}
     fi
+
     # Restore IFS
     IFS=$ifs
 }
@@ -641,7 +678,7 @@
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_TEMPEST
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/lib/template b/lib/template
index 2703788..08d10bb 100644
--- a/lib/template
+++ b/lib/template
@@ -21,7 +21,7 @@
 # - cleanup_XXXX
 
 # Save trace setting
-XTRACE=$(set +o | grep xtrace)
+_XTRACE_TEMPLATE=$(set +o | grep xtrace)
 set +o xtrace
 
 
@@ -92,7 +92,7 @@
 }
 
 # Restore xtrace
-$XTRACE
+$_XTRACE_TEMPLATE
 
 # Tell emacs to use shell-script-mode
 ## Local variables:
diff --git a/openrc b/openrc
index 71ba5a6..9bc0fd7 100644
--- a/openrc
+++ b/openrc
@@ -95,12 +95,6 @@
     fi
 fi
 
-# Currently novaclient needs you to specify the *compute api* version.  This
-# needs to match the config of your catalog returned by Keystone.
-export NOVA_VERSION=${NOVA_VERSION:-1.1}
-# In the future this will change names:
-export COMPUTE_API_VERSION=${COMPUTE_API_VERSION:-$NOVA_VERSION}
-
 # Currently cinderclient needs you to specify the *volume api* version. This
 # needs to match the config of your catalog returned by Keystone.
 export CINDER_VERSION=${CINDER_VERSION:-2}
diff --git a/samples/local.conf b/samples/local.conf
index cb293b6..34c9e8b 100644
--- a/samples/local.conf
+++ b/samples/local.conf
@@ -63,7 +63,8 @@
 # Using milestone-proposed branches
 # ---------------------------------
 
-# Uncomment these to grab the milestone-proposed branches from the repos:
+# Uncomment these to grab the milestone-proposed branches from the
+# repos:
 #CINDER_BRANCH=milestone-proposed
 #GLANCE_BRANCH=milestone-proposed
 #HORIZON_BRANCH=milestone-proposed
@@ -74,6 +75,13 @@
 #NEUTRON_BRANCH=milestone-proposed
 #SWIFT_BRANCH=milestone-proposed
 
+# Using git versions of clients
+# -----------------------------
+# By default clients are installed from pip.  See LIBS_FROM_GIT in
+# stackrc for details on getting clients from specific branches or
+# revisions.  e.g.
+# LIBS_FROM_GIT="python-ironicclient"
+# IRONICCLIENT_BRANCH=refs/changes/44/2.../1
 
 # Swift
 # -----
@@ -93,9 +101,3 @@
 # moved by setting ``SWIFT_DATA_DIR``. The directory will be created
 # if it does not exist.
 SWIFT_DATA_DIR=$DEST/data
-
-# Tempest
-# -------
-
-# Install the tempest test suite
-enable_service tempest
diff --git a/stack.sh b/stack.sh
index 8024731..09ab474 100755
--- a/stack.sh
+++ b/stack.sh
@@ -75,6 +75,7 @@
 
 # Check if run in POSIX shell
 if [[ "${POSIXLY_CORRECT}" == "y" ]]; then
+    set +o xtrace
     echo "You are running POSIX compatibility mode, DevStack requires bash 4.2 or newer."
     exit 1
 fi
@@ -85,11 +86,26 @@
 # action to create a suitable user account.
 
 if [[ $EUID -eq 0 ]]; then
-    echo "You are running this script as root."
-    echo "Cut it out."
-    echo "Really."
-    echo "If you need an account to run DevStack, do this (as root, heh) to create a non-root account:"
-    echo "$TOP_DIR/tools/create-stack-user.sh"
+    set +o xtrace
+    echo "DevStack should be run as a user with sudo permissions, "
+    echo "not root."
+    echo "A \"stack\" user configured correctly can be created with:"
+    echo " $TOP_DIR/tools/create-stack-user.sh"
+    exit 1
+fi
+
+# OpenStack is designed to run at a system level, with system level
+# installation of python packages. It does not support running under a
+# virtual env, and will fail in really odd ways if you do this. Make
+# this explicit as it has come up on the mailing list.
+if [[ -n "$VIRTUAL_ENV" ]]; then
+    set +o xtrace
+    echo "You appear to be running under a python virtualenv."
+    echo "DevStack does not support this, as we may break the"
+    echo "virtualenv you are currently in by modifying "
+    echo "external system-level components the virtualenv relies on."
+    echo "We recommend you use a separate virtual-machine if "
+    echo "you are worried about DevStack taking over your system."
     exit 1
 fi
 
@@ -97,6 +113,7 @@
 # on a lot of different environments, you sometimes run it on the
 # wrong box. This makes there be a way to prevent that.
 if [[ -e $HOME/.no-devstack ]]; then
+    set +o xtrace
     echo "You've marked this host as a no-devstack host, to save yourself from"
     echo "running devstack accidentally. If this is in error, please remove the"
     echo "~/.no-devstack file"
@@ -178,7 +195,7 @@
 
 # Warn users who aren't on an explicitly supported distro, but allow them to
 # override check and attempt installation with ``FORCE=yes ./stack``
-if [[ ! ${DISTRO} =~ (precise|trusty|utopic|vivid|7.0|wheezy|sid|testing|jessie|f21|f22|rhel7) ]]; then
+if [[ ! ${DISTRO} =~ (trusty|vivid|wily|7.0|wheezy|sid|testing|jessie|f21|f22|f23|rhel7) ]]; then
     echo "WARNING: this script has not been tested on $DISTRO"
     if [[ "$FORCE" != "yes" ]]; then
         die $LINENO "If you wish to run this script anyway run with FORCE=yes"
@@ -321,6 +338,10 @@
     sudo sed -i "s/\(^127.0.0.1.*\)/\1 $LOCAL_HOSTNAME/" /etc/hosts
 fi
 
+# Ensure python is installed
+# --------------------------
+is_package_installed python || install_package python
+
 
 # Configure Logging
 # -----------------
@@ -539,6 +560,7 @@
 source $TOP_DIR/lib/neutron-legacy
 source $TOP_DIR/lib/ldap
 source $TOP_DIR/lib/dstat
+source $TOP_DIR/lib/dlm
 
 # Extras Source
 # --------------
@@ -554,7 +576,8 @@
 
 # Generic helper to configure passwords
 function read_password {
-    XTRACE=$(set +o | grep xtrace)
+    local xtrace
+    xtrace=$(set +o | grep xtrace)
     set +o xtrace
     var=$1; msg=$2
     pw=${!var}
@@ -597,7 +620,9 @@
         eval "$var=$pw"
         echo "$var=$pw" >> $localrc
     fi
-    $XTRACE
+
+    # restore previous xtrace value
+    $xtrace
 }
 
 
@@ -716,12 +741,6 @@
 # Install required infra support libraries
 install_infra
 
-# Pre-build some problematic wheels
-if [[ -n ${WHEELHOUSE:-} && ! -d ${WHEELHOUSE:-} ]]; then
-    source $TOP_DIR/tools/build_wheels.sh
-fi
-
-
 # Extras Pre-install
 # ------------------
 # Phase: pre-install
@@ -729,6 +748,10 @@
 
 install_rpc_backend
 
+# NOTE(sdague): dlm install is conditional on one being enabled by configuration
+install_dlm
+configure_dlm
+
 if is_service_enabled $DATABASE_BACKENDS; then
     install_database
 fi
@@ -908,8 +931,8 @@
 restart_rpc_backend
 
 
-# Export Certicate Authority Bundle
-# ---------------------------------
+# Export Certificate Authority Bundle
+# -----------------------------------
 
 # If certificates were used and written to the SSL bundle file then these
 # should be exported so clients can validate their connections.
diff --git a/stackrc b/stackrc
index 4026ff8..47b54cc 100644
--- a/stackrc
+++ b/stackrc
@@ -72,18 +72,6 @@
     ENABLED_SERVICES+=,rabbit,tempest,mysql,dstat
 fi
 
-# SQLAlchemy supports multiple database drivers for each database server
-# type. For example, deployer may use MySQLdb, MySQLConnector, or oursql
-# to access MySQL database.
-#
-# When defined, the variable controls which database driver is used to
-# connect to database server. Otherwise using default driver defined for
-# each database type.
-#
-# You can find the list of currently supported drivers for each database
-# type at: http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html
-# SQLALCHEMY_DATABASE_DRIVER="mysqldb"
-
 # Global toggle for enabling services under mod_wsgi. If this is set to
 # ``True`` all services that use HTTPD + mod_wsgi as the preferred method of
 # deployment, will be deployed under Apache. If this is set to ``False`` all
@@ -91,7 +79,7 @@
 ENABLE_HTTPD_MOD_WSGI_SERVICES=True
 
 # Set the default Nova APIs to enable
-NOVA_ENABLED_APIS=ec2,osapi_compute,metadata
+NOVA_ENABLED_APIS=osapi_compute,metadata
 
 # Set the root URL for Horizon
 HORIZON_APACHE_ROOT="/dashboard"
@@ -101,13 +89,34 @@
 # ctrl-c, up-arrow, enter to restart the service. Starting services
 # this way is slightly unreliable, and a bit slower, so this can
 # be disabled for automated testing by setting this value to False.
-USE_SCREEN=True
+USE_SCREEN=$(trueorfalse True USE_SCREEN)
+
+# When using screen, should we keep a log file on disk?  You might
+# want this False if you have a long-running setup where verbose logs
+# can fill-up the host.
+# XXX: Ideally screen itself would be configured to log but just not
+# activate.  This isn't possible with the screerc syntax.  Temporary
+# logging can still be used by a developer with:
+#    C-a : logfile foo
+#    C-a : log on
+SCREEN_IS_LOGGING=$(trueorfalse True SCREEN_IS_LOGGING)
 
 # Passwords generated by interactive devstack runs
 if [[ -r $RC_DIR/.localrc.password ]]; then
     source $RC_DIR/.localrc.password
 fi
 
+# Control whether Python 3 should be used.
+export USE_PYTHON3=${USE_PYTHON3:-False}
+
+# When Python 3 is supported by an application, adding the specific
+# version of Python 3 to this variable will install the app using that
+# version of the interpreter instead of 2.7.
+export PYTHON3_VERSION=${PYTHON3_VERSION:-3.4}
+
+# Just to be more explicit on the Python 2 version to use.
+export PYTHON2_VERSION=${PYTHON2_VERSION:-2.7}
+
 # allow local overrides of env variables, including repo config
 if [[ -f $RC_DIR/localrc ]]; then
     # Old-style user-supplied config
@@ -143,11 +152,6 @@
 # requirmenets files here, in a comma-separated list
 ADDITIONAL_VENV_PACKAGES=${ADITIONAL_VENV_PACKAGES:-""}
 
-# Configure wheel cache location
-export WHEELHOUSE=${WHEELHOUSE:-$DEST/.wheelhouse}
-export PIP_WHEEL_DIR=${PIP_WHEEL_DIR:-$WHEELHOUSE}
-export PIP_FIND_LINKS=${PIP_FIND_LINKS:-file://$WHEELHOUSE}
-
 # This can be used to turn database query logging on and off
 # (currently only implemented for MySQL backend)
 DATABASE_QUERY_LOGGING=$(trueorfalse False DATABASE_QUERY_LOGGING)
@@ -263,6 +267,7 @@
 ##############
 #
 #  OpenStack Client Library Components
+#   Note default install is from pip, see LIBS_FROM_GIT
 #
 ##############
 
@@ -312,6 +317,7 @@
 ###################
 #
 #  Oslo Libraries
+#   Note default install is from pip, see LIBS_FROM_GIT
 #
 ###################
 
@@ -371,6 +377,10 @@
 GITREPO["oslo.policy"]=${OSLOPOLICY_REPO:-${GIT_BASE}/openstack/oslo.policy.git}
 GITBRANCH["oslo.policy"]=${OSLOPOLICY_BRANCH:-master}
 
+# oslo.privsep
+GITREPO["oslo.privsep"]=${OSLOPRIVSEP_REPO:-${GIT_BASE}/openstack/oslo.privsep.git}
+GITBRANCH["oslo.privsep"]=${OSLOPRIVSEP_BRANCH:-master}
+
 # oslo.reports
 GITREPO["oslo.reports"]=${OSLOREPORTS_REPO:-${GIT_BASE}/openstack/oslo.reports.git}
 GITBRANCH["oslo.reports"]=${OSLOREPORTS_BRANCH:-master}
@@ -642,9 +652,6 @@
 PRIVATE_NETWORK_NAME=${PRIVATE_NETWORK_NAME:-"private"}
 PUBLIC_NETWORK_NAME=${PUBLIC_NETWORK_NAME:-"public"}
 
-# Compatibility until it's eradicated from CI
-USE_SCREEN=${SCREEN_DEV:-$USE_SCREEN}
-
 # Set default screen name
 SCREEN_NAME=${SCREEN_NAME:-stack}
 
@@ -665,6 +672,9 @@
 # Service startup timeout
 SERVICE_TIMEOUT=${SERVICE_TIMEOUT:-60}
 
+# Service graceful shutdown timeout
+SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT=${SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT:-5}
+
 # Support alternative yum -- in future Fedora 'dnf' will become the
 # only supported installer, but for now 'yum' and 'dnf' are both
 # available in parallel with compatible CLIs.  Allow manual switching
@@ -760,6 +770,16 @@
 # Use native SSL for servers in ``SSL_ENABLED_SERVICES``
 USE_SSL=$(trueorfalse False USE_SSL)
 
+# ebtables is inherently racey. If you run it by two or more processes
+# simultaneously it will collide, badly, in the kernel and produce
+# failures or corruption of ebtables. The only way around it is for
+# all tools running ebtables to only ever do so with the --concurrent
+# flag. This requires libvirt >= 1.2.11.
+#
+# If you don't have this then the following work around will replace
+# ebtables with a wrapper script so that it is safe to run without
+# that flag.
+EBTABLES_RACE_FIX=$(trueorfalse False EBTABLES_RACE_FIX)
 
 # Following entries need to be last items in file
 
diff --git a/tests/run-process.sh b/tests/run-process.sh
index bdf1395..301b9a0 100755
--- a/tests/run-process.sh
+++ b/tests/run-process.sh
@@ -5,7 +5,7 @@
 #
 # Set USE_SCREEN True|False to change use of screen.
 #
-# This script emulates the basic exec envirnment in ``stack.sh`` to test
+# This script emulates the basic exec environment in ``stack.sh`` to test
 # the process spawn and kill operations.
 
 if [[ -z $1 ]]; then
diff --git a/tests/test_functions.sh b/tests/test_functions.sh
index f555de8..be8dc5e 100755
--- a/tests/test_functions.sh
+++ b/tests/test_functions.sh
@@ -245,4 +245,33 @@
     passed "OK"
 fi
 
+function test_export_proxy_variables {
+    echo "Testing export_proxy_variables()"
+
+    local expected results
+
+    http_proxy=http_proxy_test
+    https_proxy=https_proxy_test
+    no_proxy=no_proxy_test
+
+    export_proxy_variables
+    expected=$(echo -e "http_proxy=$http_proxy\nhttps_proxy=$https_proxy\nno_proxy=$no_proxy")
+    results=$(env | egrep '(http(s)?|no)_proxy=')
+    if [[ $expected = $results ]]; then
+        passed "OK: Proxy variables are exported when proxy variables are set"
+    else
+        failed "Expected: $expected, Failed: $results"
+    fi
+
+    unset http_proxy https_proxy no_proxy
+    export_proxy_variables
+    results=$(env | egrep '(http(s)?|no)_proxy=')
+    if [[ "" = $results ]]; then
+        passed "OK: Proxy variables aren't exported when proxy variables aren't set"
+    else
+        failed "Expected: '', Failed: $results"
+    fi
+}
+test_export_proxy_variables
+
 report_results
diff --git a/tests/test_libs_from_pypi.sh b/tests/test_libs_from_pypi.sh
index 8e8c022..f31560a 100755
--- a/tests/test_libs_from_pypi.sh
+++ b/tests/test_libs_from_pypi.sh
@@ -41,7 +41,7 @@
 ALL_LIBS+=" python-neutronclient tooz ceilometermiddleware oslo.policy"
 ALL_LIBS+=" debtcollector os-brick automaton futurist oslo.service"
 ALL_LIBS+=" oslo.cache oslo.reports"
-ALL_LIBS+=" keystoneauth ironic-lib"
+ALL_LIBS+=" keystoneauth ironic-lib oslo.privsep"
 
 # Generate the above list with
 # echo ${!GITREPO[@]}
diff --git a/tests/test_meta_config.sh b/tests/test_meta_config.sh
index a04c081..327fb56 100755
--- a/tests/test_meta_config.sh
+++ b/tests/test_meta_config.sh
@@ -23,6 +23,12 @@
     fi
 }
 
+# mock function-common:die so that it does not
+# interrupt our test script
+function die {
+    exit -1
+}
+
 TEST_1C_ADD="[eee]
 type=new
 multi = foo2"
@@ -110,6 +116,15 @@
 [DEFAULT]
 servers=10.11.12.13:80
 
+[[test8|/permission-denied.conf]]
+foo=bar
+
+[[test9|\$UNDEF]]
+foo=bar
+
+[[test10|does-not-exist-dir/test.conf]]
+foo=bar
+
 [[test-multi-sections|test-multi-sections.conf]]
 [sec-1]
 cfg_item1 = abcd
@@ -340,6 +355,36 @@
 servers = 10.11.12.13:80"
 check_result "$VAL" "$EXPECT_VAL"
 
+echo "merge_config_file test8 non-touchable conf file: "
+set +e
+# function is expected to fail and exit, running it
+# in a subprocess to let this script proceed
+(merge_config_file test.conf test8 /permission-denied.conf)
+VAL=$?
+EXPECT_VAL=255
+check_result "$VAL" "$EXPECT_VAL"
+set -e
+
+echo -n "merge_config_group test9 undefined conf file: "
+set +e
+# function is expected to fail and exit, running it
+# in a subprocess to let this script proceed
+(merge_config_group test.conf test9)
+VAL=$?
+EXPECT_VAL=255
+check_result "$VAL" "$EXPECT_VAL"
+set -e
+
+echo -n "merge_config_group test10 not directory: "
+set +e
+# function is expected to fail and exit, running it
+# in a subprocess to let this script proceed
+(merge_config_group test.conf test10)
+VAL=$?
+EXPECT_VAL=255
+check_result "$VAL" "$EXPECT_VAL"
+set -e
+
 rm -f test.conf test1c.conf test2a.conf \
     test-space.conf test-equals.conf test-strip.conf \
     test-colon.conf test-env.conf test-multiline.conf \
diff --git a/tests/test_package_ordering.sh b/tests/test_package_ordering.sh
new file mode 100755
index 0000000..a568abf
--- /dev/null
+++ b/tests/test_package_ordering.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+
+# basic test to ensure that package-install files remain sorted
+# alphabetically.
+
+TOP=$(cd $(dirname "$0")/.. && pwd)
+
+source $TOP/tests/unittest.sh
+
+PKG_FILES=$(find $TOP/files/debs $TOP/files/rpms $TOP/files/rpms-suse -type f)
+
+TMPDIR=$(mktemp -d)
+
+SORTED=${TMPDIR}/sorted
+UNSORTED=${TMPDIR}/unsorted
+
+for p in $PKG_FILES; do
+    grep -v '^#' $p > ${UNSORTED}
+    sort ${UNSORTED} > ${SORTED}
+
+    if [ -n "$(diff -c ${UNSORTED} ${SORTED})" ]; then
+        failed "$p is unsorted"
+        # output this, it's helpful to see what exactly is unsorted
+        diff -c ${UNSORTED} ${SORTED}
+    else
+        passed "$p is sorted"
+    fi
+done
+
+rm -rf ${TMPDIR}
+
+report_results
diff --git a/tests/unittest.sh b/tests/unittest.sh
index df7a8b4..26b5b8e 100644
--- a/tests/unittest.sh
+++ b/tests/unittest.sh
@@ -46,7 +46,7 @@
     ERROR=$((ERROR+1))
 }
 
-# assert string comparision of val1 equal val2, printing out msg
+# assert string comparison of val1 equal val2, printing out msg
 #  usage: assert_equal val1 val2 msg
 function assert_equal {
     local lineno
@@ -92,16 +92,17 @@
     fi
 }
 
-# print a summary of passing and failing tests, exiting
-# with an error if we have failed tests
+# Print a summary of passing and failing tests and exit
+# (with an error if we have failed tests)
 #  usage: report_results
 function report_results {
     echo "$PASS Tests PASSED"
-    if [[ $ERROR -gt 1 ]]; then
+    if [[ $ERROR -gt 0 ]]; then
         echo
         echo "The following $ERROR tests FAILED"
         echo -e "$FAILED_FUNCS"
         echo "---"
         exit 1
     fi
+    exit 0
 }
diff --git a/tools/build_wheels.sh b/tools/build_wheels.sh
deleted file mode 100755
index 14c2999..0000000
--- a/tools/build_wheels.sh
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/env bash
-#
-# **tools/build_wheels.sh** - Build a cache of Python wheels
-#
-# build_wheels.sh [package [...]]
-#
-# System package prerequisites listed in ``files/*/devlibs`` will be installed
-#
-# Builds wheels for all virtual env requirements listed in
-# ``venv-requirements.txt`` plus any supplied on the command line.
-#
-# Assumes:
-# - ``tools/install_pip.sh`` has been run and a suitable ``pip/setuptools`` is available.
-
-# If ``TOP_DIR`` is set we're being sourced rather than running stand-alone
-# or in a sub-shell
-if [[ -z "$TOP_DIR" ]]; then
-
-    set -o errexit
-    set -o nounset
-
-    # Keep track of the DevStack directory
-    TOP_DIR=$(cd $(dirname "$0")/.. && pwd)
-    FILES=$TOP_DIR/files
-
-    # Import common functions
-    source $TOP_DIR/functions
-
-    GetDistro
-
-    source $TOP_DIR/stackrc
-
-    trap err_trap ERR
-
-fi
-
-# Get additional packages to build
-MORE_PACKAGES="$@"
-
-# Exit on any errors so that errors don't compound
-function err_trap {
-    local r=$?
-    set +o xtrace
-
-    rm -rf $TMP_VENV_PATH
-
-    exit $r
-}
-
-# Get system prereqs
-install_package $(get_packages devlibs)
-
-# Get a modern ``virtualenv``
-pip_install virtualenv
-
-# Prepare the workspace
-TMP_VENV_PATH=$(mktemp -d tmp-venv-XXXX)
-virtualenv $TMP_VENV_PATH
-
-# Install modern pip and wheel
-PIP_VIRTUAL_ENV=$TMP_VENV_PATH pip_install -U pip wheel
-
-# BUG: cffi has a lot of issues. It has no stable ABI, if installed
-# code is built with a different ABI than the one that's detected at
-# load time, it tries to compile on the fly for the new ABI in the
-# install location (which will probably be /usr and not
-# writable). Also cffi is often included via setup_requires by
-# packages, which have different install rules (allowing betas) than
-# pip has.
-#
-# Because of this we must pip install cffi into the venv to build
-# wheels.
-PIP_VIRTUAL_ENV=$TMP_VENV_PATH pip_install_gr cffi
-
-# ``VENV_PACKAGES`` is a list of packages we want to pre-install
-VENV_PACKAGE_FILE=$FILES/venv-requirements.txt
-if [[ -r $VENV_PACKAGE_FILE ]]; then
-    VENV_PACKAGES=$(grep -v '^#' $VENV_PACKAGE_FILE)
-fi
-
-for pkg in ${VENV_PACKAGES,/ } ${MORE_PACKAGES}; do
-    $TMP_VENV_PATH/bin/pip wheel $pkg
-done
-
-# Clean up wheel workspace
-rm -rf $TMP_VENV_PATH
diff --git a/tools/install_ebtables_workaround.sh b/tools/install_ebtables_workaround.sh
new file mode 100755
index 0000000..45ced87
--- /dev/null
+++ b/tools/install_ebtables_workaround.sh
@@ -0,0 +1,31 @@
+#!/bin/bash -eu
+#
+# Copyright 2015 Hewlett-Packard Development Company, L.P.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+#
+# This replaces the ebtables on your system with a wrapper script that
+# does implicit locking. This is needed if libvirt < 1.2.11 on your platform.
+
+EBTABLES=/sbin/ebtables
+EBTABLESREAL=/sbin/ebtables.real
+FILES=$TOP_DIR/files
+
+if [[ -f "$EBTABLES" ]]; then
+    if file $EBTABLES | grep ELF; then
+        sudo mv $EBTABLES $EBTABLESREAL
+        sudo install -m 0755 $FILES/ebtables.workaround $EBTABLES
+        echo "Replaced ebtables with locking workaround"
+    fi
+fi
diff --git a/tools/install_pip.sh b/tools/install_pip.sh
index 13c1786..f239c7b 100755
--- a/tools/install_pip.sh
+++ b/tools/install_pip.sh
@@ -8,6 +8,7 @@
 
 # Assumptions:
 # - update pip to $INSTALL_PIP_VERSION
+# - if USE_PYTHON3=True, PYTHON3_VERSION refers to a version already installed
 
 set -o errexit
 set -o xtrace
@@ -31,6 +32,8 @@
 echo "Distro: $DISTRO"
 
 function get_versions {
+    # FIXME(dhellmann): Deal with multiple python versions here? This
+    # is just used for reporting, so maybe not?
     PIP=$(which pip 2>/dev/null || which pip-python 2>/dev/null || true)
     if [[ -n $PIP ]]; then
         PIP_VERSION=$($PIP --version | awk '{ print $2}')
@@ -75,6 +78,9 @@
         touch $LOCAL_PIP.downloaded
     fi
     sudo -H -E python $LOCAL_PIP
+    if python3_enabled; then
+        sudo -H -E python${PYTHON3_VERSION} $LOCAL_PIP
+    fi
 }
 
 
@@ -110,7 +116,12 @@
 # Do pip
 
 # Eradicate any and all system packages
-uninstall_package python-pip
+
+# python in f23 depends on the python-pip package
+if ! { is_fedora && [[ $DISTRO == "f23" ]]; }; then
+    uninstall_package python-pip
+    uninstall_package python3-pip
+fi
 
 install_get_pip
 
@@ -118,6 +129,7 @@
     configure_pypi_alternative_url
 fi
 
+set -x
 pip_install -U setuptools
 
 get_versions
diff --git a/tools/install_prereqs.sh b/tools/install_prereqs.sh
index a07e58d..031f8a8 100755
--- a/tools/install_prereqs.sh
+++ b/tools/install_prereqs.sh
@@ -61,7 +61,7 @@
 # ================
 
 # Install package requirements
-PACKAGES=$(get_packages general $ENABLED_SERVICES)
+PACKAGES=$(get_packages general,$ENABLED_SERVICES)
 PACKAGES="$PACKAGES $(get_plugin_packages)"
 
 if is_ubuntu && echo $PACKAGES | grep -q dkms ; then
@@ -81,6 +81,9 @@
     fi
 fi
 
+if python3_enabled; then
+    install_python3
+fi
 
 # Mark end of run
 # ---------------
diff --git a/tools/worlddump.py b/tools/worlddump.py
index 1b337a9..97e4d94 100755
--- a/tools/worlddump.py
+++ b/tools/worlddump.py
@@ -86,8 +86,10 @@
 
 
 def ebtables_dump():
+    tables = ['filter', 'nat', 'broute']
     _header("EB Tables Dump")
-    _dump_cmd("sudo ebtables -L")
+    for table in tables:
+        _dump_cmd("sudo ebtables -t %s -L" % table)
 
 
 def iptables_dump():
diff --git a/tox.ini b/tox.ini
index 0df9877..f9d04f2 100644
--- a/tox.ini
+++ b/tox.ini
@@ -9,23 +9,24 @@
 
 [testenv:bashate]
 deps =
-   {env:BASHATE_INSTALL_PATH:bashate==0.3.1}
+   {env:BASHATE_INSTALL_PATH:bashate==0.3.2}
 whitelist_externals = bash
 commands = bash -c "find {toxinidir}             \
-         -not \( -type d -name .?\* -prune \)    \ # prune all 'dot' dirs
-         -not \( -type d -name doc -prune \)     \ # skip documentation
-         -not \( -type d -name shocco -prune \)  \ # skip shocco
-         -type f                                 \ # only files
-         -not -name \*~                          \ # skip editors, readme, etc
+         -not \( -type d -name .?\* -prune \)    \
+         -not \( -type d -name doc -prune \)     \
+         -not \( -type d -name shocco -prune \)  \
+         -type f                                 \
+         -not -name \*~                          \
          -not -name \*.md                        \
          \(                                      \
           -name \*.sh -or                        \
+          -name \*.orig -or                      \
           -name \*rc -or                         \
           -name functions\* -or                  \
-          -wholename \*/inc/\* -or               \ # /inc files and
-          -wholename \*/lib/\*                   \ # /lib files are shell, but
-         \)                                      \ #   have no extension
-         -print0 | xargs -0 bashate -v -iE006"
+          -wholename \*/inc/\* -or               \
+          -wholename \*/lib/\*                   \
+         \)                                      \
+         -print0 | xargs -0 bashate -v -iE006 -eE005,E042"
 
 [testenv:docs]
 deps =
diff --git a/unstack.sh b/unstack.sh
index 30447a7..8eded83 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -69,6 +69,7 @@
 source $TOP_DIR/lib/neutron-legacy
 source $TOP_DIR/lib/ldap
 source $TOP_DIR/lib/dstat
+source $TOP_DIR/lib/dlm
 
 # Extras Source
 # --------------
@@ -172,6 +173,10 @@
     stop_dstat
 fi
 
+if is_service_enabled zookeeper; then
+    stop_zookeeper
+fi
+
 # Clean up the remainder of the screen processes
 SCREEN=$(which screen)
 if [[ -n "$SCREEN" ]]; then