Merge "Revert "Switch fernet to be the default token provider""
diff --git a/Makefile b/Makefile
index a94d60a..970d800 100644
--- a/Makefile
+++ b/Makefile
@@ -15,7 +15,7 @@
 DEST=/opt/stack
 
 all:
-	echo "This just saved you from a terrible mistake!"
+	@echo "This just saved you from a terrible mistake!"
 
 # Do Some Work
 stack:
diff --git a/clean.sh b/clean.sh
index b18f28e..0641bff 100755
--- a/clean.sh
+++ b/clean.sh
@@ -49,6 +49,7 @@
 source $TOP_DIR/lib/cinder
 source $TOP_DIR/lib/swift
 source $TOP_DIR/lib/heat
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 
 set -o xtrace
@@ -137,9 +138,10 @@
 FILES_TO_CLEAN=".localrc.auto .localrc.password "
 FILES_TO_CLEAN+="docs/files docs/html shocco/ "
 FILES_TO_CLEAN+="stack-screenrc test*.conf* test.ini* "
-FILES_TO_CLEAN+=".stackenv .prereqs "
-FILES_TO_CLEAN+="~/.config/openstack"
+FILES_TO_CLEAN+=".stackenv .prereqs"
 
 for file in $FILES_TO_CLEAN; do
     rm -rf $TOP_DIR/$file
 done
+
+rm -rf ~/.config/openstack
diff --git a/data/devstack-plugins-registry.header b/data/devstack-plugins-registry.header
index f105fe9..6119ab5 100644
--- a/data/devstack-plugins-registry.header
+++ b/data/devstack-plugins-registry.header
@@ -1,20 +1,23 @@
 ..
-  Note to patch submitters: this file is covered by a periodic proposal
-  job.  You should edit the files data/devstack-plugins-registry.footer
-  data/devstack-plugins-registry.header instead of this one.
+
+  Note to patch submitters:
+
+  # ============================= #
+  # THIS FILE IS AUTOGENERATED !  #
+  # ============================= #
+
+  ** Plugins are found automatically and added to this list **
+
+  This file is created by a periodic proposal job.  You should not
+  edit this file.
+
+  You should edit the files data/devstack-plugins-registry.footer
+  data/devstack-plugins-registry.header to modify this text.
 
 ==========================
  DevStack Plugin Registry
 ==========================
 
-Since we've created the external plugin mechanism, it's gotten used by
-a lot of projects. The following is a list of plugins that currently
-exist. Any project that wishes to list their plugin here is welcomed
-to.
-
-Detected Plugins
-================
-
-The following are plugins that a script has found in the openstack/
-namespace, which includes but is not limited to official OpenStack
-projects.
+The following list is an automatically-generated collection of
+available DevStack plugins.  This includes, but is not limited to,
+official OpenStack projects.
diff --git a/doc/source/changes.rst b/doc/source/changes.rst
deleted file mode 100644
index 19fce0f..0000000
--- a/doc/source/changes.rst
+++ /dev/null
@@ -1,12 +0,0 @@
-=======
-Changes
-=======
-
-Recent Changes What's been happening?
-=====================================
-
-These are the commits to DevStack for the last six months. For the
-complete list see `the DevStack project in
-Gerrit <https://review.openstack.org/#/q/status:merged+project:openstack-dev/devstack,n,z>`__.
-
-%GIT_LOG%
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index 0493f8f..1f5797c 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -62,8 +62,7 @@
 A specific meta-section ``local|localrc`` is used to provide a default
 ``localrc`` file (actually ``.localrc.auto``). This allows all custom
 settings for DevStack to be contained in a single file. If ``localrc``
-exists it will be used instead to preserve backward-compatibility. More
-details on the :doc:`contents of local.conf <local.conf>` are available.
+exists it will be used instead to preserve backward-compatibility.
 
 ::
 
@@ -84,6 +83,76 @@
 fragment and MUST conform to the shell requirements, specifically no
 whitespace around ``=`` (equals).
 
+openrc
+======
+
+``openrc`` configures login credentials suitable for use with the
+OpenStack command-line tools. ``openrc`` sources ``stackrc`` at the
+beginning (which in turn sources the ``localrc`` section of
+``local.conf``) in order to pick up ``HOST_IP`` and/or ``SERVICE_HOST``
+to use in the endpoints. The values shown below are the default values.
+
+OS\_PROJECT\_NAME (OS\_TENANT\_NAME)
+    Keystone has
+    standardized the term *project* as the entity that owns resources. In
+    some places references still exist to the previous term
+    *tenant* for this use. Also, *project\_name* is preferred to
+    *project\_id*.  OS\_TENANT\_NAME remains supported for compatibility
+    with older tools.
+
+    ::
+
+        OS_PROJECT_NAME=demo
+
+OS\_USERNAME
+    In addition to the owning entity (project), OpenStack calls the entity
+    performing the action *user*.
+
+    ::
+
+        OS_USERNAME=demo
+
+OS\_PASSWORD
+    Keystone's default authentication requires a password be provided.
+    The usual cautions about putting passwords in environment variables
+    apply, for most DevStack uses this may be an acceptable tradeoff.
+
+    ::
+
+        OS_PASSWORD=secret
+
+HOST\_IP, SERVICE\_HOST
+    Set API endpoint host using ``HOST_IP``. ``SERVICE_HOST`` may also
+    be used to specify the endpoint, which is convenient for some
+    ``local.conf`` configurations. Typically, ``HOST_IP`` is set in the
+    ``localrc`` section.
+
+    ::
+
+        HOST_IP=127.0.0.1
+        SERVICE_HOST=$HOST_IP
+
+OS\_AUTH\_URL
+    Authenticating against an OpenStack cloud using Keystone returns a
+    *Token* and *Service Catalog*. The catalog contains the endpoints
+    for all services the user/tenant has access to - including Nova,
+    Glance, Keystone and Swift.
+
+    ::
+
+        OS_AUTH_URL=http://$SERVICE_HOST:5000/v2.0
+
+KEYSTONECLIENT\_DEBUG, NOVACLIENT\_DEBUG
+    Set command-line client log level to ``DEBUG``. These are commented
+    out by default.
+
+    ::
+
+        # export KEYSTONECLIENT_DEBUG=1
+        # export NOVACLIENT_DEBUG=1
+
+
+
 .. _minimal-configuration:
 
 Minimal Configuration
@@ -145,6 +214,37 @@
 .. contents::
    :local:
 
+Service Repos
+-------------
+
+The Git repositories used to check out the source for each service are
+controlled by a pair of variables set for each service.  ``*_REPO``
+points to the repository and ``*_BRANCH`` selects which branch to
+check out. These may be overridden in ``local.conf`` to pull source
+from a different repo for testing, such as a Gerrit branch
+proposal. ``GIT_BASE`` points to the primary repository server.
+
+    ::
+
+        NOVA_REPO=$GIT_BASE/openstack/nova.git
+        NOVA_BRANCH=master
+
+To pull a branch directly from Gerrit, get the repo and branch from
+the Gerrit review page:
+
+    ::
+
+        git fetch https://review.openstack.org/p/openstack/nova refs/changes/50/5050/1 && git checkout FETCH_HEAD
+
+    The repo is the stanza following ``fetch`` and the branch is the
+    stanza following that:
+
+    ::
+
+        NOVA_REPO=https://review.openstack.org/p/openstack/nova
+        NOVA_BRANCH=refs/changes/50/5050/1
+
+
 Installation Directory
 ----------------------
 
@@ -423,8 +523,8 @@
 ----------
 
 ``IP_VERSION`` can be used to configure DevStack to create either an
-IPv4, IPv6, or dual-stack tenant data-network by with either
-``IP_VERSION=4``, ``IP_VERSION=6``, or ``IP_VERSION=4+6``
+IPv4, IPv6, or dual-stack self service project data-network by with
+either ``IP_VERSION=4``, ``IP_VERSION=6``, or ``IP_VERSION=4+6``
 respectively.  This functionality requires that the Neutron networking
 service is enabled by setting the following options:
 
@@ -513,6 +613,18 @@
 with multiple replicas you can do so by customizing the variable
 ``SWIFT_REPLICAS`` in your ``localrc`` section (usually to 3).
 
+You can manually override the ring building to use specific storage
+nodes, for example when you want to test a multinode environment. In
+this case you have to set a space-separated list of IPs in
+``SWIFT_STORAGE_IPS`` in your ``localrc`` section that should be used
+as Swift storage nodes.
+Please note that this does not create a multinode setup, it is only
+used when adding nodes to the Swift rings.
+
+::
+
+    SWIFT_STORAGE_IPS="192.168.1.10 192.168.1.11 192.168.1.12"
+
 Swift S3
 ++++++++
 
@@ -630,6 +742,16 @@
     KEYSTONE_SERVICE_HOST=<KEYSTONE_IP_ADDRESS_FROM_REGION_ONE>
     KEYSTONE_AUTH_HOST=<KEYSTONE_IP_ADDRESS_FROM_REGION_ONE>
     REGION_NAME=RegionTwo
+    KEYSTONE_REGION_NAME=RegionOne
+
+In the devstack for RegionOne, we set REGION_NAME as RegionOne, so region of
+the services started in this devstack are registered as RegionOne. In devstack
+for RegionTwo, similarly, we set REGION_NAME as RegionTwo since we want
+services started in this devstack to be registered in RegionTwo. But Keystone
+service is started and registered in RegionOne, not RegionTwo, so we use
+KEYSTONE_REGION_NAME to specify the region of Keystone service.
+KEYSTONE_REGION_NAME has a default value the same as REGION_NAME thus we omit
+it in the configuration of RegionOne.
 
 Disabling Identity API v2
 +++++++++++++++++++++++++
@@ -640,3 +762,40 @@
 ::
 
     ENABLE_IDENTITY_V2=False
+
+Exercises
+~~~~~~~~~
+
+``exerciserc`` is used to configure settings for the exercise scripts.
+The values shown below are the default values. These can all be
+overridden by setting them in the ``localrc`` section.
+
+* Max time to wait while vm goes from build to active state
+
+    ::
+
+        ACTIVE_TIMEOUT==30
+
+* Max time to wait for proper IP association and dis-association.
+
+    ::
+
+        ASSOCIATE_TIMEOUT=15
+
+* Max time till the vm is bootable
+
+    ::
+
+        BOOT_TIMEOUT=30
+
+* Max time from run instance command until it is running
+
+    ::
+
+        RUNNING_TIMEOUT=$(($BOOT_TIMEOUT + $ACTIVE_TIMEOUT))
+
+* Max time to wait for a vm to terminate
+
+    ::
+
+        TERMINATE_TIMEOUT=30
diff --git a/doc/source/exerciserc.rst b/doc/source/exerciserc.rst
deleted file mode 100644
index dacae2e..0000000
--- a/doc/source/exerciserc.rst
+++ /dev/null
@@ -1,42 +0,0 @@
-==============================
-exerciserc - Exercise Settings
-==============================
-
-``exerciserc`` is used to configure settings for the exercise scripts.
-The values shown below are the default values. These can all be
-overridden by setting them in the ``localrc`` section.
-
-ACTIVE\_TIMEOUT
-    Max time to wait while vm goes from build to active state
-
-    ::
-
-        ACTIVE_TIMEOUT==30
-
-ASSOCIATE\_TIMEOUT
-    Max time to wait for proper IP association and dis-association.
-
-    ::
-
-        ASSOCIATE_TIMEOUT=15
-
-BOOT\_TIMEOUT
-    Max time till the vm is bootable
-
-    ::
-
-        BOOT_TIMEOUT=30
-
-RUNNING\_TIMEOUT
-    Max time from run instance command until it is running
-
-    ::
-
-        RUNNING_TIMEOUT=$(($BOOT_TIMEOUT + $ACTIVE_TIMEOUT))
-
-TERMINATE\_TIMEOUT
-    Max time to wait for a vm to terminate
-
-    ::
-
-        TERMINATE_TIMEOUT=30
diff --git a/doc/source/guides/lxc.rst b/doc/source/guides/lxc.rst
index a719d60..9549ed2 100644
--- a/doc/source/guides/lxc.rst
+++ b/doc/source/guides/lxc.rst
@@ -88,7 +88,7 @@
 
 You can also ssh into your container. On your host, run
 ``sudo lxc-info -n devstack`` to get the IP address (e.g. 
-``ssh ubuntu@$(sudo lxc-info -n p2 | awk '/IP/ { print $2 }')``).
+``ssh ubuntu@$(sudo lxc-info -n devstack | awk '/IP/ { print $2 }')``).
 
 Run Devstack
 -------------
diff --git a/doc/source/guides/neutron.rst b/doc/source/guides/neutron.rst
index 6ac3993..fe6f629 100644
--- a/doc/source/guides/neutron.rst
+++ b/doc/source/guides/neutron.rst
@@ -15,8 +15,8 @@
 network interface that is available. In this scenario, the physical
 interface is added to the Open vSwitch bridge, and the IP address of
 the laptop is migrated onto the bridge interface. That way, the
-physical interface can be used to transmit tenant network traffic,
-the OpenStack API traffic, and management traffic.
+physical interface can be used to transmit self service project
+network traffic, the OpenStack API traffic, and management traffic.
 
 
 .. warning::
@@ -88,7 +88,6 @@
         FIXED_RANGE="10.0.0.0/24"
         Q_FLOATING_ALLOCATION_POOL=start=172.18.161.250,end=172.18.161.254
         PUBLIC_NETWORK_GATEWAY="172.18.161.1"
-        Q_L3_ENABLED=True
         PUBLIC_INTERFACE=eth0
 
         # Open vSwitch provider networking configuration
@@ -222,12 +221,12 @@
 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.
+IP traffic for project networks can be received from the physical
+network infrastructure (and the internet), and routed to self service
+project 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 project network traffic, using the VXLAN tunneling
+protocol, flows between each compute node where project instances run.
 
 
 
@@ -381,13 +380,12 @@
 
         ## Neutron options
         Q_USE_SECGROUP=True
-        ENABLE_TENANT_VLANS=True
-        TENANT_VLAN_RANGE=3001:4000
+        ENABLE_PROJECT_VLANS=True
+        PROJECT_VLAN_RANGE=3001:4000
         PHYSICAL_NETWORK=default
         OVS_PHYSICAL_BRIDGE=br-ex
 
         Q_USE_PROVIDER_NETWORKING=True
-        Q_L3_ENABLED=False
 
         # Do not use Nova-Network
         disable_service n-net
@@ -434,13 +432,12 @@
         OVS_PHYSICAL_BRIDGE=br-ex
         PUBLIC_INTERFACE=eth1
         Q_USE_PROVIDER_NETWORKING=True
-        Q_L3_ENABLED=False
 
 Compute node 2's configuration will be exactly the same, except
 ``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) -
 DevStack will automatically add the network interface defined in
 ``PUBLIC_INTERFACE`` to the ``OVS_PHYSICAL_BRIDGE``
 
@@ -543,7 +540,6 @@
     FIXED_RANGE="10.0.0.0/24"
     Q_FLOATING_ALLOCATION_POOL=start=172.18.161.250,end=172.18.161.254
     PUBLIC_NETWORK_GATEWAY="172.18.161.1"
-    Q_L3_ENABLED=True
     PUBLIC_INTERFACE=eth0
 
     Q_USE_PROVIDERNET_FOR_PUBLIC=True
@@ -553,4 +549,3 @@
     LB_PHYSICAL_INTERFACE=eth0
     PUBLIC_PHYSICAL_NETWORK=default
     LB_INTERFACE_MAPPINGS=default:eth0
-
diff --git a/doc/source/index.rst b/doc/source/index.rst
index c79b2ce..68ec174 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -1,8 +1,16 @@
-DevStack - an OpenStack Community Production
-============================================
+DevStack
+========
 
 .. image:: assets/images/logo-blue.png
 
+DevStack is a series of extensible scripts used to quickly bring up a
+complete OpenStack environment.  It is used interactively as a
+development environment and as the basis for much of the OpenStack
+project's functional testing.
+
+The source is available at
+`<https://git.openstack.org/cgit/openstack-dev/devstack>`__.
+
 .. toctree::
    :glob:
    :maxdepth: 1
@@ -12,7 +20,6 @@
    plugins
    plugin-registry
    faq
-   changes
    hacking
 
 Quick Start
@@ -56,15 +63,12 @@
 
        devstack/tools/create-stack-user.sh; su stack
 
-#. Start the install
+#. Start the install, this will take a few minutes.
 
    ::
 
        cd devstack; ./stack.sh
 
-   It takes a few minutes, we recommend `reading the
-   script <stack.sh.html>`__ while it is building.
-
 Guides
 ======
 
@@ -147,11 +151,6 @@
 
 :doc:`Extending DevStack with new features <plugins>`
 
-Recent Changes
---------------
-
-:doc:`An incomplete summary of recent changes <changes>`
-
 FAQ
 ---
 
@@ -162,94 +161,3 @@
 
 :doc:`Pitching in to make DevStack a better place <hacking>`
 
-Code
-====
-
-*A look at the bits that make it all go*
-
-Scripts
--------
-
-* `stack.sh <stack.sh.html>`__ - The main script
-* `functions <functions.html>`__ - DevStack-specific functions
-* `functions-common <functions-common.html>`__ - Functions shared with other projects
-* `lib/apache <lib/apache.html>`__
-* `lib/ceph <lib/ceph.html>`__
-* `lib/cinder <lib/cinder.html>`__
-* `lib/database <lib/database.html>`__
-* `lib/dstat <lib/dstat.html>`__
-* `lib/glance <lib/glance.html>`__
-* `lib/heat <lib/heat.html>`__
-* `lib/horizon <lib/horizon.html>`__
-* `lib/infra <lib/infra.html>`__
-* `lib/keystone <lib/keystone.html>`__
-* `lib/ldap <lib/ldap.html>`__
-* `lib/neutron-legacy <lib/neutron-legacy.html>`__
-* `lib/nova <lib/nova.html>`__
-* `lib/oslo <lib/oslo.html>`__
-* `lib/rpc\_backend <lib/rpc_backend.html>`__
-* `lib/swift <lib/swift.html>`__
-* `lib/tempest <lib/tempest.html>`__
-* `lib/tls <lib/tls.html>`__
-* `lib/trove <lib/trove.html>`__
-* `unstack.sh <unstack.sh.html>`__
-* `clean.sh <clean.sh.html>`__
-* `run\_tests.sh <run_tests.sh.html>`__
-
-* `extras.d/60-ceph.sh <extras.d/60-ceph.sh.html>`__
-* `extras.d/70-tuskar.sh <extras.d/70-tuskar.sh.html>`__
-* `extras.d/80-tempest.sh <extras.d/80-tempest.sh.html>`__
-
-* `inc/ini-config <inc/ini-config.html>`__
-* `inc/meta-config <inc/meta-config.html>`__
-* `inc/python <inc/python.html>`__
-
-* `pkg/elasticsearch.sh <pkg/elasticsearch.sh.html>`_
-
-Configuration
--------------
-
-.. toctree::
-   :glob:
-   :maxdepth: 1
-
-   local.conf
-   stackrc
-   openrc
-   exerciserc
-
-Tools
------
-
-* `tools/build\_docs.sh <tools/build_docs.sh.html>`__
-* `tools/build\_venv.sh <tools/build_venv.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>`__
-* `tools/info.sh <tools/info.sh.html>`__
-* `tools/install\_pip.sh <tools/install_pip.sh.html>`__
-* `tools/install\_prereqs.sh <tools/install_prereqs.sh.html>`__
-* `tools/make\_cert.sh <tools/make_cert.sh.html>`__
-* `tools/upload\_image.sh <tools/upload_image.sh.html>`__
-
-Samples
--------
-
-* `local.sh <samples/local.sh.html>`__
-
-Exercises
----------
-
-* `exercise.sh <exercise.sh.html>`__
-* `exercises/aggregates.sh <exercises/aggregates.sh.html>`__
-* `exercises/boot\_from\_volume.sh <exercises/boot_from_volume.sh.html>`__
-* `exercises/bundle.sh <exercises/bundle.sh.html>`__
-* `exercises/client-args.sh <exercises/client-args.sh.html>`__
-* `exercises/client-env.sh <exercises/client-env.sh.html>`__
-* `exercises/euca.sh <exercises/euca.sh.html>`__
-* `exercises/floating\_ips.sh <exercises/floating_ips.sh.html>`__
-* `exercises/horizon.sh <exercises/horizon.sh.html>`__
-* `exercises/neutron-adv-test.sh <exercises/neutron-adv-test.sh.html>`__
-* `exercises/sec\_groups.sh <exercises/sec_groups.sh.html>`__
-* `exercises/swift.sh <exercises/swift.sh.html>`__
-* `exercises/volumes.sh <exercises/volumes.sh.html>`__
diff --git a/doc/source/local.conf.rst b/doc/source/local.conf.rst
deleted file mode 100644
index a1ca60a..0000000
--- a/doc/source/local.conf.rst
+++ /dev/null
@@ -1,9 +0,0 @@
-==========================
-local.conf - User Settings
-==========================
-
-``local.conf`` is a user-maintained settings file that is sourced in
-``stackrc``. It contains a section that replaces the historical
-``localrc`` file. See the description of
-:doc:`local.conf <configuration>` for more details about the mechanics
-of the file.
diff --git a/doc/source/openrc.rst b/doc/source/openrc.rst
deleted file mode 100644
index 4e7f075..0000000
--- a/doc/source/openrc.rst
+++ /dev/null
@@ -1,68 +0,0 @@
-=====================================
-openrc - User Authentication Settings
-=====================================
-
-``openrc`` configures login credentials suitable for use with the
-OpenStack command-line tools. ``openrc`` sources ``stackrc`` at the
-beginning (which in turn sources the ``localrc`` section of
-``local.conf``) in order to pick up ``HOST_IP`` and/or ``SERVICE_HOST``
-to use in the endpoints. The values shown below are the default values.
-
-OS\_PROJECT\_NAME (OS\_TENANT\_NAME)
-    Keystone has
-    standardized the term *project* as the entity that owns resources. In
-    some places references still exist to the previous term
-    *tenant* for this use. Also, *project\_name* is preferred to
-    *project\_id*.  OS\_TENANT\_NAME remains supported for compatibility
-    with older tools.
-
-    ::
-
-        OS_PROJECT_NAME=demo
-
-OS\_USERNAME
-    In addition to the owning entity (project), OpenStack calls the entity
-    performing the action *user*.
-
-    ::
-
-        OS_USERNAME=demo
-
-OS\_PASSWORD
-    Keystone's default authentication requires a password be provided.
-    The usual cautions about putting passwords in environment variables
-    apply, for most DevStack uses this may be an acceptable tradeoff.
-
-    ::
-
-        OS_PASSWORD=secret
-
-HOST\_IP, SERVICE\_HOST
-    Set API endpoint host using ``HOST_IP``. ``SERVICE_HOST`` may also
-    be used to specify the endpoint, which is convenient for some
-    ``local.conf`` configurations. Typically, ``HOST_IP`` is set in the
-    ``localrc`` section.
-
-    ::
-
-        HOST_IP=127.0.0.1
-        SERVICE_HOST=$HOST_IP
-
-OS\_AUTH\_URL
-    Authenticating against an OpenStack cloud using Keystone returns a
-    *Token* and *Service Catalog*. The catalog contains the endpoints
-    for all services the user/tenant has access to - including Nova,
-    Glance, Keystone and Swift.
-
-    ::
-
-        OS_AUTH_URL=http://$SERVICE_HOST:5000/v2.0
-
-KEYSTONECLIENT\_DEBUG, NOVACLIENT\_DEBUG
-    Set command-line client log level to ``DEBUG``. These are commented
-    out by default.
-
-    ::
-
-        # export KEYSTONECLIENT_DEBUG=1
-        # export NOVACLIENT_DEBUG=1
diff --git a/doc/source/plugin-registry.rst b/doc/source/plugin-registry.rst
index b467123..a2721b4 100644
--- a/doc/source/plugin-registry.rst
+++ b/doc/source/plugin-registry.rst
@@ -1,200 +1,129 @@
 ..
-  Note to patch submitters: this file is covered by a periodic proposal
-  job.  You should edit the files data/devstack-plugins-registry.footer
-  data/devstack-plugins-registry.header instead of this one.
+
+  Note to patch submitters:
+
+  # ============================= #
+  # THIS FILE IS AUTOGENERATED !  #
+  # ============================= #
+
+  ** Plugins are found automatically and added to this list **
+
+  This file is created by a periodic proposal job.  You should not
+  edit this file.
+
+  You should edit the files data/devstack-plugins-registry.footer
+  data/devstack-plugins-registry.header to modify this text.
 
 ==========================
  DevStack Plugin Registry
 ==========================
 
-Since we've created the external plugin mechanism, it's gotten used by
-a lot of projects. The following is a list of plugins that currently
-exist. Any project that wishes to list their plugin here is welcomed
-to.
+The following list is an automatically-generated collection of
+available DevStack plugins.  This includes, but is not limited to,
+official OpenStack projects.
 
-Detected Plugins
-================
 
-The following are plugins that a script has found in the openstack/
-namespace, which includes but is not limited to official OpenStack
-projects.
+====================================== ===
+Plugin Name                            URL
+====================================== ===
+aodh                                   `git://git.openstack.org/openstack/aodh <https://git.openstack.org/cgit/openstack/aodh>`__
+app-catalog-ui                         `git://git.openstack.org/openstack/app-catalog-ui <https://git.openstack.org/cgit/openstack/app-catalog-ui>`__
+astara                                 `git://git.openstack.org/openstack/astara <https://git.openstack.org/cgit/openstack/astara>`__
+barbican                               `git://git.openstack.org/openstack/barbican <https://git.openstack.org/cgit/openstack/barbican>`__
+blazar                                 `git://git.openstack.org/openstack/blazar <https://git.openstack.org/cgit/openstack/blazar>`__
+broadview-collector                    `git://git.openstack.org/openstack/broadview-collector <https://git.openstack.org/cgit/openstack/broadview-collector>`__
+ceilometer                             `git://git.openstack.org/openstack/ceilometer <https://git.openstack.org/cgit/openstack/ceilometer>`__
+ceilometer-powervm                     `git://git.openstack.org/openstack/ceilometer-powervm <https://git.openstack.org/cgit/openstack/ceilometer-powervm>`__
+cerberus                               `git://git.openstack.org/openstack/cerberus <https://git.openstack.org/cgit/openstack/cerberus>`__
+cloudkitty                             `git://git.openstack.org/openstack/cloudkitty <https://git.openstack.org/cgit/openstack/cloudkitty>`__
+collectd-ceilometer-plugin             `git://git.openstack.org/openstack/collectd-ceilometer-plugin <https://git.openstack.org/cgit/openstack/collectd-ceilometer-plugin>`__
+congress                               `git://git.openstack.org/openstack/congress <https://git.openstack.org/cgit/openstack/congress>`__
+cue                                    `git://git.openstack.org/openstack/cue <https://git.openstack.org/cgit/openstack/cue>`__
+designate                              `git://git.openstack.org/openstack/designate <https://git.openstack.org/cgit/openstack/designate>`__
+devstack-plugin-additional-pkg-repos   `git://git.openstack.org/openstack/devstack-plugin-additional-pkg-repos <https://git.openstack.org/cgit/openstack/devstack-plugin-additional-pkg-repos>`__
+devstack-plugin-amqp1                  `git://git.openstack.org/openstack/devstack-plugin-amqp1 <https://git.openstack.org/cgit/openstack/devstack-plugin-amqp1>`__
+devstack-plugin-bdd                    `git://git.openstack.org/openstack/devstack-plugin-bdd <https://git.openstack.org/cgit/openstack/devstack-plugin-bdd>`__
+devstack-plugin-ceph                   `git://git.openstack.org/openstack/devstack-plugin-ceph <https://git.openstack.org/cgit/openstack/devstack-plugin-ceph>`__
+devstack-plugin-glusterfs              `git://git.openstack.org/openstack/devstack-plugin-glusterfs <https://git.openstack.org/cgit/openstack/devstack-plugin-glusterfs>`__
+devstack-plugin-hdfs                   `git://git.openstack.org/openstack/devstack-plugin-hdfs <https://git.openstack.org/cgit/openstack/devstack-plugin-hdfs>`__
+devstack-plugin-kafka                  `git://git.openstack.org/openstack/devstack-plugin-kafka <https://git.openstack.org/cgit/openstack/devstack-plugin-kafka>`__
+devstack-plugin-nfs                    `git://git.openstack.org/openstack/devstack-plugin-nfs <https://git.openstack.org/cgit/openstack/devstack-plugin-nfs>`__
+devstack-plugin-pika                   `git://git.openstack.org/openstack/devstack-plugin-pika <https://git.openstack.org/cgit/openstack/devstack-plugin-pika>`__
+devstack-plugin-sheepdog               `git://git.openstack.org/openstack/devstack-plugin-sheepdog <https://git.openstack.org/cgit/openstack/devstack-plugin-sheepdog>`__
+devstack-plugin-zmq                    `git://git.openstack.org/openstack/devstack-plugin-zmq <https://git.openstack.org/cgit/openstack/devstack-plugin-zmq>`__
+dragonflow                             `git://git.openstack.org/openstack/dragonflow <https://git.openstack.org/cgit/openstack/dragonflow>`__
+drbd-devstack                          `git://git.openstack.org/openstack/drbd-devstack <https://git.openstack.org/cgit/openstack/drbd-devstack>`__
+ec2-api                                `git://git.openstack.org/openstack/ec2-api <https://git.openstack.org/cgit/openstack/ec2-api>`__
+freezer                                `git://git.openstack.org/openstack/freezer <https://git.openstack.org/cgit/openstack/freezer>`__
+freezer-api                            `git://git.openstack.org/openstack/freezer-api <https://git.openstack.org/cgit/openstack/freezer-api>`__
+freezer-web-ui                         `git://git.openstack.org/openstack/freezer-web-ui <https://git.openstack.org/cgit/openstack/freezer-web-ui>`__
+gce-api                                `git://git.openstack.org/openstack/gce-api <https://git.openstack.org/cgit/openstack/gce-api>`__
+gnocchi                                `git://git.openstack.org/openstack/gnocchi <https://git.openstack.org/cgit/openstack/gnocchi>`__
+group-based-policy                     `git://git.openstack.org/openstack/group-based-policy <https://git.openstack.org/cgit/openstack/group-based-policy>`__
+ironic                                 `git://git.openstack.org/openstack/ironic <https://git.openstack.org/cgit/openstack/ironic>`__
+ironic-inspector                       `git://git.openstack.org/openstack/ironic-inspector <https://git.openstack.org/cgit/openstack/ironic-inspector>`__
+kingbird                               `git://git.openstack.org/openstack/kingbird <https://git.openstack.org/cgit/openstack/kingbird>`__
+kuryr                                  `git://git.openstack.org/openstack/kuryr <https://git.openstack.org/cgit/openstack/kuryr>`__
+magnum                                 `git://git.openstack.org/openstack/magnum <https://git.openstack.org/cgit/openstack/magnum>`__
+magnum-ui                              `git://git.openstack.org/openstack/magnum-ui <https://git.openstack.org/cgit/openstack/magnum-ui>`__
+manila                                 `git://git.openstack.org/openstack/manila <https://git.openstack.org/cgit/openstack/manila>`__
+mistral                                `git://git.openstack.org/openstack/mistral <https://git.openstack.org/cgit/openstack/mistral>`__
+monasca-api                            `git://git.openstack.org/openstack/monasca-api <https://git.openstack.org/cgit/openstack/monasca-api>`__
+monasca-log-api                        `git://git.openstack.org/openstack/monasca-log-api <https://git.openstack.org/cgit/openstack/monasca-log-api>`__
+murano                                 `git://git.openstack.org/openstack/murano <https://git.openstack.org/cgit/openstack/murano>`__
+networking-6wind                       `git://git.openstack.org/openstack/networking-6wind <https://git.openstack.org/cgit/openstack/networking-6wind>`__
+networking-bagpipe                     `git://git.openstack.org/openstack/networking-bagpipe <https://git.openstack.org/cgit/openstack/networking-bagpipe>`__
+networking-bgpvpn                      `git://git.openstack.org/openstack/networking-bgpvpn <https://git.openstack.org/cgit/openstack/networking-bgpvpn>`__
+networking-brocade                     `git://git.openstack.org/openstack/networking-brocade <https://git.openstack.org/cgit/openstack/networking-brocade>`__
+networking-calico                      `git://git.openstack.org/openstack/networking-calico <https://git.openstack.org/cgit/openstack/networking-calico>`__
+networking-cisco                       `git://git.openstack.org/openstack/networking-cisco <https://git.openstack.org/cgit/openstack/networking-cisco>`__
+networking-fortinet                    `git://git.openstack.org/openstack/networking-fortinet <https://git.openstack.org/cgit/openstack/networking-fortinet>`__
+networking-generic-switch              `git://git.openstack.org/openstack/networking-generic-switch <https://git.openstack.org/cgit/openstack/networking-generic-switch>`__
+networking-infoblox                    `git://git.openstack.org/openstack/networking-infoblox <https://git.openstack.org/cgit/openstack/networking-infoblox>`__
+networking-l2gw                        `git://git.openstack.org/openstack/networking-l2gw <https://git.openstack.org/cgit/openstack/networking-l2gw>`__
+networking-midonet                     `git://git.openstack.org/openstack/networking-midonet <https://git.openstack.org/cgit/openstack/networking-midonet>`__
+networking-mlnx                        `git://git.openstack.org/openstack/networking-mlnx <https://git.openstack.org/cgit/openstack/networking-mlnx>`__
+networking-nec                         `git://git.openstack.org/openstack/networking-nec <https://git.openstack.org/cgit/openstack/networking-nec>`__
+networking-odl                         `git://git.openstack.org/openstack/networking-odl <https://git.openstack.org/cgit/openstack/networking-odl>`__
+networking-ofagent                     `git://git.openstack.org/openstack/networking-ofagent <https://git.openstack.org/cgit/openstack/networking-ofagent>`__
+networking-onos                        `git://git.openstack.org/openstack/networking-onos <https://git.openstack.org/cgit/openstack/networking-onos>`__
+networking-ovn                         `git://git.openstack.org/openstack/networking-ovn <https://git.openstack.org/cgit/openstack/networking-ovn>`__
+networking-ovs-dpdk                    `git://git.openstack.org/openstack/networking-ovs-dpdk <https://git.openstack.org/cgit/openstack/networking-ovs-dpdk>`__
+networking-plumgrid                    `git://git.openstack.org/openstack/networking-plumgrid <https://git.openstack.org/cgit/openstack/networking-plumgrid>`__
+networking-powervm                     `git://git.openstack.org/openstack/networking-powervm <https://git.openstack.org/cgit/openstack/networking-powervm>`__
+networking-sfc                         `git://git.openstack.org/openstack/networking-sfc <https://git.openstack.org/cgit/openstack/networking-sfc>`__
+networking-vsphere                     `git://git.openstack.org/openstack/networking-vsphere <https://git.openstack.org/cgit/openstack/networking-vsphere>`__
+neutron                                `git://git.openstack.org/openstack/neutron <https://git.openstack.org/cgit/openstack/neutron>`__
+neutron-lbaas                          `git://git.openstack.org/openstack/neutron-lbaas <https://git.openstack.org/cgit/openstack/neutron-lbaas>`__
+neutron-lbaas-dashboard                `git://git.openstack.org/openstack/neutron-lbaas-dashboard <https://git.openstack.org/cgit/openstack/neutron-lbaas-dashboard>`__
+neutron-vpnaas                         `git://git.openstack.org/openstack/neutron-vpnaas <https://git.openstack.org/cgit/openstack/neutron-vpnaas>`__
+nova-docker                            `git://git.openstack.org/openstack/nova-docker <https://git.openstack.org/cgit/openstack/nova-docker>`__
+nova-powervm                           `git://git.openstack.org/openstack/nova-powervm <https://git.openstack.org/cgit/openstack/nova-powervm>`__
+octavia                                `git://git.openstack.org/openstack/octavia <https://git.openstack.org/cgit/openstack/octavia>`__
+osprofiler                             `git://git.openstack.org/openstack/osprofiler <https://git.openstack.org/cgit/openstack/osprofiler>`__
+python-freezerclient                   `git://git.openstack.org/openstack/python-freezerclient <https://git.openstack.org/cgit/openstack/python-freezerclient>`__
+rally                                  `git://git.openstack.org/openstack/rally <https://git.openstack.org/cgit/openstack/rally>`__
+sahara                                 `git://git.openstack.org/openstack/sahara <https://git.openstack.org/cgit/openstack/sahara>`__
+sahara-dashboard                       `git://git.openstack.org/openstack/sahara-dashboard <https://git.openstack.org/cgit/openstack/sahara-dashboard>`__
+scalpels                               `git://git.openstack.org/openstack/scalpels <https://git.openstack.org/cgit/openstack/scalpels>`__
+searchlight                            `git://git.openstack.org/openstack/searchlight <https://git.openstack.org/cgit/openstack/searchlight>`__
+searchlight-ui                         `git://git.openstack.org/openstack/searchlight-ui <https://git.openstack.org/cgit/openstack/searchlight-ui>`__
+senlin                                 `git://git.openstack.org/openstack/senlin <https://git.openstack.org/cgit/openstack/senlin>`__
+smaug                                  `git://git.openstack.org/openstack/smaug <https://git.openstack.org/cgit/openstack/smaug>`__
+smaug-dashboard                        `git://git.openstack.org/openstack/smaug-dashboard <https://git.openstack.org/cgit/openstack/smaug-dashboard>`__
+solum                                  `git://git.openstack.org/openstack/solum <https://git.openstack.org/cgit/openstack/solum>`__
+tacker                                 `git://git.openstack.org/openstack/tacker <https://git.openstack.org/cgit/openstack/tacker>`__
+tap-as-a-service                       `git://git.openstack.org/openstack/tap-as-a-service <https://git.openstack.org/cgit/openstack/tap-as-a-service>`__
+tricircle                              `git://git.openstack.org/openstack/tricircle <https://git.openstack.org/cgit/openstack/tricircle>`__
+trove                                  `git://git.openstack.org/openstack/trove <https://git.openstack.org/cgit/openstack/trove>`__
+trove-dashboard                        `git://git.openstack.org/openstack/trove-dashboard <https://git.openstack.org/cgit/openstack/trove-dashboard>`__
+vitrage                                `git://git.openstack.org/openstack/vitrage <https://git.openstack.org/cgit/openstack/vitrage>`__
+vitrage-dashboard                      `git://git.openstack.org/openstack/vitrage-dashboard <https://git.openstack.org/cgit/openstack/vitrage-dashboard>`__
+vmware-nsx                             `git://git.openstack.org/openstack/vmware-nsx <https://git.openstack.org/cgit/openstack/vmware-nsx>`__
+watcher                                `git://git.openstack.org/openstack/watcher <https://git.openstack.org/cgit/openstack/watcher>`__
+watcher-dashboard                      `git://git.openstack.org/openstack/watcher-dashboard <https://git.openstack.org/cgit/openstack/watcher-dashboard>`__
+zaqar                                  `git://git.openstack.org/openstack/zaqar <https://git.openstack.org/cgit/openstack/zaqar>`__
+zaqar-ui                               `git://git.openstack.org/openstack/zaqar-ui <https://git.openstack.org/cgit/openstack/zaqar-ui>`__
+====================================== ===
 
-+----------------------------+-------------------------------------------------------------------------+
-|Plugin Name                 |URL                                                                      |
-+----------------------------+-------------------------------------------------------------------------+
-|aodh                        |git://git.openstack.org/openstack/aodh                                   |
-+----------------------------+-------------------------------------------------------------------------+
-|app-catalog-ui              |git://git.openstack.org/openstack/app-catalog-ui                         |
-+----------------------------+-------------------------------------------------------------------------+
-|astara                      |git://git.openstack.org/openstack/astara                                 |
-+----------------------------+-------------------------------------------------------------------------+
-|barbican                    |git://git.openstack.org/openstack/barbican                               |
-+----------------------------+-------------------------------------------------------------------------+
-|blazar                      |git://git.openstack.org/openstack/blazar                                 |
-+----------------------------+-------------------------------------------------------------------------+
-|broadview-collector         |git://git.openstack.org/openstack/broadview-collector                    |
-+----------------------------+-------------------------------------------------------------------------+
-|ceilometer                  |git://git.openstack.org/openstack/ceilometer                             |
-+----------------------------+-------------------------------------------------------------------------+
-|ceilometer-powervm          |git://git.openstack.org/openstack/ceilometer-powervm                     |
-+----------------------------+-------------------------------------------------------------------------+
-|cerberus                    |git://git.openstack.org/openstack/cerberus                               |
-+----------------------------+-------------------------------------------------------------------------+
-|cloudkitty                  |git://git.openstack.org/openstack/cloudkitty                             |
-+----------------------------+-------------------------------------------------------------------------+
-|collectd-ceilometer-plugin  |git://git.openstack.org/openstack/collectd-ceilometer-plugin             |
-+----------------------------+-------------------------------------------------------------------------+
-|congress                    |git://git.openstack.org/openstack/congress                               |
-+----------------------------+-------------------------------------------------------------------------+
-|cue                         |git://git.openstack.org/openstack/cue                                    |
-+----------------------------+-------------------------------------------------------------------------+
-|designate                   |git://git.openstack.org/openstack/designate                              |
-+----------------------------+-------------------------------------------------------------------------+
-|devstack-plugin-amqp1       |git://git.openstack.org/openstack/devstack-plugin-amqp1                  |
-+----------------------------+-------------------------------------------------------------------------+
-|devstack-plugin-bdd         |git://git.openstack.org/openstack/devstack-plugin-bdd                    |
-+----------------------------+-------------------------------------------------------------------------+
-|devstack-plugin-ceph        |git://git.openstack.org/openstack/devstack-plugin-ceph                   |
-+----------------------------+-------------------------------------------------------------------------+
-|devstack-plugin-glusterfs   |git://git.openstack.org/openstack/devstack-plugin-glusterfs              |
-+----------------------------+-------------------------------------------------------------------------+
-|devstack-plugin-hdfs        |git://git.openstack.org/openstack/devstack-plugin-hdfs                   |
-+----------------------------+-------------------------------------------------------------------------+
-|devstack-plugin-kafka       |git://git.openstack.org/openstack/devstack-plugin-kafka                  |
-+----------------------------+-------------------------------------------------------------------------+
-|devstack-plugin-pika        |git://git.openstack.org/openstack/devstack-plugin-pika                   |
-+----------------------------+-------------------------------------------------------------------------+
-|devstack-plugin-sheepdog    |git://git.openstack.org/openstack/devstack-plugin-sheepdog               |
-+----------------------------+-------------------------------------------------------------------------+
-|devstack-plugin-zmq         |git://git.openstack.org/openstack/devstack-plugin-zmq                    |
-+----------------------------+-------------------------------------------------------------------------+
-|dragonflow                  |git://git.openstack.org/openstack/dragonflow                             |
-+----------------------------+-------------------------------------------------------------------------+
-|drbd-devstack               |git://git.openstack.org/openstack/drbd-devstack                          |
-+----------------------------+-------------------------------------------------------------------------+
-|ec2-api                     |git://git.openstack.org/openstack/ec2-api                                |
-+----------------------------+-------------------------------------------------------------------------+
-|freezer                     |git://git.openstack.org/openstack/freezer                                |
-+----------------------------+-------------------------------------------------------------------------+
-|freezer-api                 |git://git.openstack.org/openstack/freezer-api                            |
-+----------------------------+-------------------------------------------------------------------------+
-|freezer-web-ui              |git://git.openstack.org/openstack/freezer-web-ui                         |
-+----------------------------+-------------------------------------------------------------------------+
-|gce-api                     |git://git.openstack.org/openstack/gce-api                                |
-+----------------------------+-------------------------------------------------------------------------+
-|gnocchi                     |git://git.openstack.org/openstack/gnocchi                                |
-+----------------------------+-------------------------------------------------------------------------+
-|ironic                      |git://git.openstack.org/openstack/ironic                                 |
-+----------------------------+-------------------------------------------------------------------------+
-|ironic-inspector            |git://git.openstack.org/openstack/ironic-inspector                       |
-+----------------------------+-------------------------------------------------------------------------+
-|kingbird                    |git://git.openstack.org/openstack/kingbird                               |
-+----------------------------+-------------------------------------------------------------------------+
-|kuryr                       |git://git.openstack.org/openstack/kuryr                                  |
-+----------------------------+-------------------------------------------------------------------------+
-|magnum                      |git://git.openstack.org/openstack/magnum                                 |
-+----------------------------+-------------------------------------------------------------------------+
-|manila                      |git://git.openstack.org/openstack/manila                                 |
-+----------------------------+-------------------------------------------------------------------------+
-|mistral                     |git://git.openstack.org/openstack/mistral                                |
-+----------------------------+-------------------------------------------------------------------------+
-|monasca-api                 |git://git.openstack.org/openstack/monasca-api                            |
-+----------------------------+-------------------------------------------------------------------------+
-|murano                      |git://git.openstack.org/openstack/murano                                 |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-6wind            |git://git.openstack.org/openstack/networking-6wind                       |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-bagpipe          |git://git.openstack.org/openstack/networking-bagpipe                     |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-bgpvpn           |git://git.openstack.org/openstack/networking-bgpvpn                      |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-brocade          |git://git.openstack.org/openstack/networking-brocade                     |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-calico           |git://git.openstack.org/openstack/networking-calico                      |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-cisco            |git://git.openstack.org/openstack/networking-cisco                       |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-fortinet         |git://git.openstack.org/openstack/networking-fortinet                    |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-generic-switch   |git://git.openstack.org/openstack/networking-generic-switch              |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-infoblox         |git://git.openstack.org/openstack/networking-infoblox                    |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-l2gw             |git://git.openstack.org/openstack/networking-l2gw                        |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-midonet          |git://git.openstack.org/openstack/networking-midonet                     |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-mlnx             |git://git.openstack.org/openstack/networking-mlnx                        |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-nec              |git://git.openstack.org/openstack/networking-nec                         |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-odl              |git://git.openstack.org/openstack/networking-odl                         |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-ofagent          |git://git.openstack.org/openstack/networking-ofagent                     |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-ovn              |git://git.openstack.org/openstack/networking-ovn                         |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-ovs-dpdk         |git://git.openstack.org/openstack/networking-ovs-dpdk                    |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-plumgrid         |git://git.openstack.org/openstack/networking-plumgrid                    |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-powervm          |git://git.openstack.org/openstack/networking-powervm                     |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-sfc              |git://git.openstack.org/openstack/networking-sfc                         |
-+----------------------------+-------------------------------------------------------------------------+
-|networking-vsphere          |git://git.openstack.org/openstack/networking-vsphere                     |
-+----------------------------+-------------------------------------------------------------------------+
-|neutron                     |git://git.openstack.org/openstack/neutron                                |
-+----------------------------+-------------------------------------------------------------------------+
-|neutron-lbaas               |git://git.openstack.org/openstack/neutron-lbaas                          |
-+----------------------------+-------------------------------------------------------------------------+
-|neutron-lbaas-dashboard     |git://git.openstack.org/openstack/neutron-lbaas-dashboard                |
-+----------------------------+-------------------------------------------------------------------------+
-|neutron-vpnaas              |git://git.openstack.org/openstack/neutron-vpnaas                         |
-+----------------------------+-------------------------------------------------------------------------+
-|nova-docker                 |git://git.openstack.org/openstack/nova-docker                            |
-+----------------------------+-------------------------------------------------------------------------+
-|nova-powervm                |git://git.openstack.org/openstack/nova-powervm                           |
-+----------------------------+-------------------------------------------------------------------------+
-|octavia                     |git://git.openstack.org/openstack/octavia                                |
-+----------------------------+-------------------------------------------------------------------------+
-|osprofiler                  |git://git.openstack.org/openstack/osprofiler                             |
-+----------------------------+-------------------------------------------------------------------------+
-|rally                       |git://git.openstack.org/openstack/rally                                  |
-+----------------------------+-------------------------------------------------------------------------+
-|sahara                      |git://git.openstack.org/openstack/sahara                                 |
-+----------------------------+-------------------------------------------------------------------------+
-|sahara-dashboard            |git://git.openstack.org/openstack/sahara-dashboard                       |
-+----------------------------+-------------------------------------------------------------------------+
-|scalpels                    |git://git.openstack.org/openstack/scalpels                               |
-+----------------------------+-------------------------------------------------------------------------+
-|searchlight                 |git://git.openstack.org/openstack/searchlight                            |
-+----------------------------+-------------------------------------------------------------------------+
-|senlin                      |git://git.openstack.org/openstack/senlin                                 |
-+----------------------------+-------------------------------------------------------------------------+
-|smaug                       |git://git.openstack.org/openstack/smaug                                  |
-+----------------------------+-------------------------------------------------------------------------+
-|solum                       |git://git.openstack.org/openstack/solum                                  |
-+----------------------------+-------------------------------------------------------------------------+
-|tacker                      |git://git.openstack.org/openstack/tacker                                 |
-+----------------------------+-------------------------------------------------------------------------+
-|tap-as-a-service            |git://git.openstack.org/openstack/tap-as-a-service                       |
-+----------------------------+-------------------------------------------------------------------------+
-|tricircle                   |git://git.openstack.org/openstack/tricircle                              |
-+----------------------------+-------------------------------------------------------------------------+
-|trove                       |git://git.openstack.org/openstack/trove                                  |
-+----------------------------+-------------------------------------------------------------------------+
-|trove-dashboard             |git://git.openstack.org/openstack/trove-dashboard                        |
-+----------------------------+-------------------------------------------------------------------------+
-|vitrage                     |git://git.openstack.org/openstack/vitrage                                |
-+----------------------------+-------------------------------------------------------------------------+
-|vitrage-dashboard           |git://git.openstack.org/openstack/vitrage-dashboard                      |
-+----------------------------+-------------------------------------------------------------------------+
-|vmware-nsx                  |git://git.openstack.org/openstack/vmware-nsx                             |
-+----------------------------+-------------------------------------------------------------------------+
-|watcher                     |git://git.openstack.org/openstack/watcher                                |
-+----------------------------+-------------------------------------------------------------------------+
-|watcher-dashboard           |git://git.openstack.org/openstack/watcher-dashboard                      |
-+----------------------------+-------------------------------------------------------------------------+
-|zaqar                       |git://git.openstack.org/openstack/zaqar                                  |
-+----------------------------+-------------------------------------------------------------------------+
+
diff --git a/doc/source/stackrc.rst b/doc/source/stackrc.rst
deleted file mode 100644
index 81d4b80..0000000
--- a/doc/source/stackrc.rst
+++ /dev/null
@@ -1,66 +0,0 @@
-===========================
-stackrc - DevStack Settings
-===========================
-
-``stackrc`` is the primary configuration file for DevStack. It contains
-all of the settings that control the services started and the
-repositories used to download the source for those services. ``stackrc``
-sources the ``localrc`` section of ``local.conf`` to perform the default
-overrides.
-
-DATABASE\_TYPE
-    Select the database backend to use. The default is ``mysql``,
-    ``postgresql`` is also available.
-ENABLED\_SERVICES
-    Specify which services to launch. These generally correspond to
-    screen tabs. The default includes: Glance (API and Registry),
-    Keystone, Nova (API, Certificate, Object Store, Compute, Network,
-    Scheduler, Certificate Authentication), Cinder
-    (Scheduler, API, Volume), Horizon, MySQL, RabbitMQ, Tempest.
-
-    ::
-
-        ENABLED_SERVICES=g-api,g-reg,key,n-api,n-crt,n-cpu,n-net,n-cond,c-sch,c-api,c-vol,n-sch,n-cauth,horizon,rabbit,tempest,$DATABASE_TYPE
-
-    Other services that are not enabled by default can be enabled in
-    ``localrc``. For example, to add Swift, use the following service
-    names:
-
-    ::
-
-        enable_service s-proxy s-object s-container s-account
-
-    A service can similarly be disabled:
-
-    ::
-
-        disable_service horizon
-
-Service Repos
-    The Git repositories used to check out the source for each service
-    are controlled by a pair of variables set for each service.
-    ``*_REPO`` points to the repository and ``*_BRANCH`` selects which
-    branch to check out. These may be overridden in ``local.conf`` to
-    pull source from a different repo for testing, such as a Gerrit
-    branch proposal. ``GIT_BASE`` points to the primary repository
-    server.
-
-    ::
-
-        NOVA_REPO=$GIT_BASE/openstack/nova.git
-        NOVA_BRANCH=master
-
-    To pull a branch directly from Gerrit, get the repo and branch from
-    the Gerrit review page:
-
-    ::
-
-        git fetch https://review.openstack.org/p/openstack/nova refs/changes/50/5050/1 && git checkout FETCH_HEAD
-
-    The repo is the stanza following ``fetch`` and the branch is the
-    stanza following that:
-
-    ::
-
-        NOVA_REPO=https://review.openstack.org/p/openstack/nova
-        NOVA_BRANCH=refs/changes/50/5050/1
diff --git a/driver_certs/cinder_driver_cert.sh b/driver_certs/cinder_driver_cert.sh
deleted file mode 100755
index d066e06..0000000
--- a/driver_certs/cinder_driver_cert.sh
+++ /dev/null
@@ -1,106 +0,0 @@
-#!/usr/bin/env bash
-
-# **cinder_cert.sh**
-
-# This script is a simple wrapper around the tempest volume api tests
-# It requires that you have a working and functional devstack install
-# and that you've enabled your device driver by making the necessary
-# modifications to /etc/cinder/cinder.conf
-
-# This script will refresh your openstack repo's and restart the cinder
-# services to pick up your driver changes.
-# please NOTE; this script assumes your devstack install is functional
-# and includes tempest. A good first step is to make sure you can
-# create volumes on your device before you even try and run this script.
-
-# It also assumes default install location (/opt/stack/xxx)
-# to aid in debug, you should also verify that you've added
-# an output directory for screen logs:
-#
-#     SCREEN_LOGDIR=/opt/stack/screen-logs
-
-set -o pipefail
-
-CERT_DIR=$(cd $(dirname "$0") && pwd)
-TOP_DIR=$(cd $CERT_DIR/..; pwd)
-
-source $TOP_DIR/functions
-source $TOP_DIR/stackrc
-source $TOP_DIR/openrc
-source $TOP_DIR/lib/infra
-source $TOP_DIR/lib/tempest
-source $TOP_DIR/lib/cinder
-
-TEMPFILE=`mktemp`
-RECLONE=True
-
-function log_message {
-    MESSAGE=$1
-    STEP_HEADER=$2
-    if [[ "$STEP_HEADER" = "True" ]]; then
-        echo -e "\n========================================================" | tee -a $TEMPFILE
-    fi
-    echo -e `date +%m/%d/%y/%T:`"${MESSAGE}" | tee -a $TEMPFILE
-    if [[ "$STEP_HEADER" = "True" ]]; then
-        echo -e "========================================================" | tee -a $TEMPFILE
-    fi
-}
-
-if [[ "$OFFLINE" = "True" ]]; then
-    echo "ERROR: Driver cert requires fresh clone/pull from ${CINDER_BRANCH}"
-    echo "       Please set OFFLINE=False and retry."
-    exit 1
-fi
-
-log_message "RUNNING CINDER DRIVER CERTIFICATION CHECK", True
-log_message "Output is being logged to: $TEMPFILE"
-
-cd $CINDER_DIR
-log_message "Cloning to ${CINDER_REPO}...", True
-install_cinder
-
-log_message "Pull a fresh Clone of cinder repo...", True
-git status | tee -a $TEMPFILE
-git log --pretty=oneline -n 1 | tee -a $TEMPFILE
-
-log_message "Gathering copy of cinder.conf file (passwords will be scrubbed)...", True
-cat /etc/cinder/cinder.conf | egrep -v "(^#.*|^$)" | tee -a $TEMPFILE
-sed -i "s/\(.*password.*=\).*$/\1 xxx/i" $TEMPFILE
-log_message "End of cinder.conf.", True
-
-cd $TOP_DIR
-# Verify tempest is installed/enabled
-if ! is_service_enabled tempest; then
-    log_message "ERROR!!! Cert requires tempest in enabled_services!", True
-    log_message"       Please add tempest to enabled_services and retry."
-    exit 1
-fi
-
-cd $TEMPEST_DIR
-install_tempest
-
-log_message "Verify tempest is current....", True
-git status | tee -a $TEMPFILE
-log_message "Check status and get latest commit..."
-git log --pretty=oneline -n 1 | tee -a $TEMPFILE
-
-
-#stop and restart cinder services
-log_message "Restart Cinder services...", True
-stop_cinder
-sleep 1
-start_cinder
-sleep 5
-
-# run tempest api/volume/test_*
-log_message "Run the actual tempest volume tests (./tools/pretty_tox.sh volume)...", True
-./tools/pretty_tox.sh volume 2>&1 | tee -a $TEMPFILE
-if [[ $? = 0 ]]; then
-    log_message "CONGRATULATIONS!!!  Device driver PASSED!", True
-    log_message "Submit output: ($TEMPFILE)"
-    exit 0
-else
-    log_message "SORRY!!!  Device driver FAILED!", True
-    log_message "Check output in $TEMPFILE"
-    exit 1
-fi
diff --git a/exercises/boot_from_volume.sh b/exercises/boot_from_volume.sh
index 5409859..84ac08f 100755
--- a/exercises/boot_from_volume.sh
+++ b/exercises/boot_from_volume.sh
@@ -32,6 +32,7 @@
 
 # Import project functions
 source $TOP_DIR/lib/cinder
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 
 # Import configuration
diff --git a/exercises/floating_ips.sh b/exercises/floating_ips.sh
index 4b72a00..485208b 100755
--- a/exercises/floating_ips.sh
+++ b/exercises/floating_ips.sh
@@ -31,6 +31,7 @@
 source $TOP_DIR/openrc
 
 # Import project functions
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 
 # Import exercise configuration
diff --git a/exercises/neutron-adv-test.sh b/exercises/neutron-adv-test.sh
index a3128a8..8115006 100755
--- a/exercises/neutron-adv-test.sh
+++ b/exercises/neutron-adv-test.sh
@@ -37,6 +37,7 @@
 source $TOP_DIR/openrc
 
 # Import neutron functions
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 
 # If neutron is not enabled we exit with exitcode 55, which means exercise is skipped.
diff --git a/exercises/volumes.sh b/exercises/volumes.sh
index f95c81f..0de1226 100755
--- a/exercises/volumes.sh
+++ b/exercises/volumes.sh
@@ -32,6 +32,7 @@
 
 # Import project functions
 source $TOP_DIR/lib/cinder
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 
 # Import exercise configuration
diff --git a/functions b/functions
index 1bfb8a5..2736dc0 100644
--- a/functions
+++ b/functions
@@ -41,6 +41,9 @@
     file=${file#$RC_DIR/}
     printf "%-40s " "$file:${called[1]}:${called[0]}"
 }
+# PS4 is exported to child shells and uses the 'short_source' function, so
+# export it so child shells have access to the 'short_source' function also.
+export -f short_source
 
 
 # Retrieve an image from a URL and upload into Glance.
@@ -83,7 +86,7 @@
     # OpenVZ-format images are provided as .tar.gz, but not decompressed prior to loading
     if [[ "$image_url" =~ 'openvz' ]]; then
         image_name="${image_fname%.tar.gz}"
-        openstack --os-cloud=devstack-admin image create "$image_name" --public --container-format ami --disk-format ami < "${image}"
+        openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name" --public --container-format ami --disk-format ami < "${image}"
         return
     fi
 
@@ -197,7 +200,7 @@
         vmdk_adapter_type="${props[1]:-$vmdk_adapter_type}"
         vmdk_net_adapter="${props[2]:-$vmdk_net_adapter}"
 
-        openstack --os-cloud=devstack-admin image create "$image_name" --public --container-format bare --disk-format vmdk --property vmware_disktype="$vmdk_disktype" --property vmware_adaptertype="$vmdk_adapter_type" --property hw_vif_model="$vmdk_net_adapter" < "${image}"
+        openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name" --public --container-format bare --disk-format vmdk --property vmware_disktype="$vmdk_disktype" --property vmware_adaptertype="$vmdk_adapter_type" --property hw_vif_model="$vmdk_net_adapter" < "${image}"
         return
     fi
 
@@ -214,7 +217,7 @@
             force_vm_mode="--property vm_mode=xen"
         fi
         openstack \
-            --os-cloud=devstack-admin \
+            --os-cloud=devstack-admin --os-region-name="$REGION_NAME" \
             image create \
             "$image_name" --public \
             --container-format=ovf --disk-format=vhd \
@@ -228,7 +231,7 @@
     if [[ "$image_url" =~ '.xen-raw.tgz' ]]; then
         image_name="${image_fname%.xen-raw.tgz}"
         openstack \
-            --os-cloud=devstack-admin \
+            --os-cloud=devstack-admin --os-region-name="$REGION_NAME" \
             image create \
             "$image_name" --public \
             --container-format=tgz --disk-format=raw \
@@ -244,7 +247,7 @@
         fi
 
         openstack \
-            --os-cloud=devstack-admin \
+            --os-cloud=devstack-admin --os-region-name="$REGION_NAME" \
             image create \
             "$image_name" --public \
             --container-format=bare --disk-format=ploop \
@@ -327,9 +330,9 @@
 
     if [ "$container_format" = "bare" ]; then
         if [ "$unpack" = "zcat" ]; then
-            openstack --os-cloud=devstack-admin image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < <(zcat --force "${image}")
+            openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < <(zcat --force "${image}")
         else
-            openstack --os-cloud=devstack-admin image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < "${image}"
+            openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name" $img_property --public --container-format=$container_format --disk-format $disk_format < "${image}"
         fi
     else
         # Use glance client to add the kernel the root filesystem.
@@ -337,12 +340,12 @@
         # kernel for use when uploading the root filesystem.
         local kernel_id="" ramdisk_id="";
         if [ -n "$kernel" ]; then
-            kernel_id=$(openstack --os-cloud=devstack-admin image create "$image_name-kernel" $img_property --public --container-format aki --disk-format aki < "$kernel" | grep ' id ' | get_field 2)
+            kernel_id=$(openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name-kernel" $img_property --public --container-format aki --disk-format aki < "$kernel" | grep ' id ' | get_field 2)
         fi
         if [ -n "$ramdisk" ]; then
-            ramdisk_id=$(openstack --os-cloud=devstack-admin image create "$image_name-ramdisk" $img_property --public --container-format ari --disk-format ari < "$ramdisk" | grep ' id ' | get_field 2)
+            ramdisk_id=$(openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "$image_name-ramdisk" $img_property --public --container-format ari --disk-format ari < "$ramdisk" | grep ' id ' | get_field 2)
         fi
-        openstack --os-cloud=devstack-admin image create "${image_name%.img}" $img_property --public --container-format ami --disk-format ami ${kernel_id:+--property kernel_id=$kernel_id} ${ramdisk_id:+--property ramdisk_id=$ramdisk_id} < "${image}"
+        openstack --os-cloud=devstack-admin --os-region-name="$REGION_NAME" image create "${image_name%.img}" $img_property --public --container-format ami --disk-format ami ${kernel_id:+--property kernel_id=$kernel_id} ${ramdisk_id:+--property ramdisk_id=$ramdisk_id} < "${image}"
     fi
 }
 
diff --git a/functions-common b/functions-common
index b0352d3..a56a0ab 100644
--- a/functions-common
+++ b/functions-common
@@ -123,7 +123,7 @@
         --os-project-name admin
 
     # CLean up any old clouds.yaml files we had laying around
-    rm -f ~$STACK_USER/.config/openstack/clouds.yaml
+    rm -f $(eval echo ~"$STACK_USER")/.config/openstack/clouds.yaml
 }
 
 # trueorfalse <True|False> <VAR>
@@ -380,7 +380,7 @@
         DISTRO="sle${os_RELEASE%.*}"
     elif [[ "$os_VENDOR" =~ (Red.*Hat) || \
         "$os_VENDOR" =~ (CentOS) || \
-        "$os_VENDOR" =~ (OracleLinux) || \
+        "$os_VENDOR" =~ (OracleServer) || \
         "$os_VENDOR" =~ (Virtuozzo) ]]; then
         # Drop the . release as we assume it's compatible
         # XXX re-evaluate when we get RHEL10
@@ -427,7 +427,7 @@
         GetOSVersion
     fi
 
-    [ "$os_VENDOR" = "OracleLinux" ]
+    [ "$os_VENDOR" = "OracleServer" ]
 }
 
 
@@ -441,7 +441,7 @@
 
     [ "$os_VENDOR" = "Fedora" ] || [ "$os_VENDOR" = "Red Hat" ] || \
         [ "$os_VENDOR" = "RedHatEnterpriseServer" ] || \
-        [ "$os_VENDOR" = "CentOS" ] || [ "$os_VENDOR" = "OracleLinux" ] || \
+        [ "$os_VENDOR" = "CentOS" ] || [ "$os_VENDOR" = "OracleServer" ] || \
         [ "$os_VENDOR" = "Virtuozzo" ] || [ "$os_VENDOR" = "kvmibm" ]
 }
 
@@ -840,27 +840,49 @@
     echo $role_id
 }
 
+# Returns the domain parts of a function call if present
+# Usage: _get_domain_args [<user_domain> <project_domain>]
+function _get_domain_args {
+    local domain
+    domain=""
+
+    if [[ -n "$1" ]]; then
+        domain="$domain --user-domain $1"
+    fi
+    if [[ -n "$2" ]]; then
+        domain="$domain --project-domain $2"
+    fi
+
+    echo $domain
+}
+
 # Gets or adds user role to project
-# Usage: get_or_add_user_project_role <role> <user> <project>
+# Usage: get_or_add_user_project_role <role> <user> <project> [<user_domain> <project_domain>]
 function get_or_add_user_project_role {
     local user_role_id
+
+    domain_args=$(_get_domain_args $4 $5)
+
     # Gets user role id
     user_role_id=$(openstack role list \
         --user $2 \
         --column "ID" \
         --project $3 \
         --column "Name" \
+        $domain_args \
         | grep " $1 " | get_field 1)
     if [[ -z "$user_role_id" ]]; then
         # Adds role to user and get it
         openstack role add $1 \
             --user $2 \
-            --project $3
+            --project $3 \
+            $domain_args
         user_role_id=$(openstack role list \
             --user $2 \
             --column "ID" \
             --project $3 \
             --column "Name" \
+            $domain_args \
             | grep " $1 " | get_field 1)
     fi
     echo $user_role_id
@@ -2041,14 +2063,14 @@
         # TODO(dtroyer): Remove these legacy special-cases after the is_XXX_enabled()
         #                are implemented
 
-        [[ ${service} == n-cell-* && ${ENABLED_SERVICES} =~ "n-cell" ]] && enabled=0
-        [[ ${service} == n-cpu-* && ${ENABLED_SERVICES} =~ "n-cpu" ]] && enabled=0
-        [[ ${service} == "nova" && ${ENABLED_SERVICES} =~ "n-" ]] && enabled=0
-        [[ ${service} == "glance" && ${ENABLED_SERVICES} =~ "g-" ]] && enabled=0
-        [[ ${service} == "neutron" && ${ENABLED_SERVICES} =~ "q-" ]] && enabled=0
-        [[ ${service} == "trove" && ${ENABLED_SERVICES} =~ "tr-" ]] && enabled=0
-        [[ ${service} == "swift" && ${ENABLED_SERVICES} =~ "s-" ]] && enabled=0
-        [[ ${service} == s-* && ${ENABLED_SERVICES} =~ "swift" ]] && enabled=0
+        [[ ${service} == n-cell-* && ,${ENABLED_SERVICES} =~ ,"n-cell" ]] && enabled=0
+        [[ ${service} == n-cpu-* && ,${ENABLED_SERVICES} =~ ,"n-cpu" ]] && enabled=0
+        [[ ${service} == "nova" && ,${ENABLED_SERVICES} =~ ,"n-" ]] && enabled=0
+        [[ ${service} == "glance" && ,${ENABLED_SERVICES} =~ ,"g-" ]] && enabled=0
+        [[ ${service} == "neutron" && ,${ENABLED_SERVICES} =~ ,"q-" ]] && enabled=0
+        [[ ${service} == "trove" && ,${ENABLED_SERVICES} =~ ,"tr-" ]] && enabled=0
+        [[ ${service} == "swift" && ,${ENABLED_SERVICES} =~ ,"s-" ]] && enabled=0
+        [[ ${service} == s-* && ,${ENABLED_SERVICES} =~ ,"swift" ]] && enabled=0
     done
 
     $xtrace
diff --git a/lib/cinder b/lib/cinder
index 4df7de8..9c818c6 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -386,6 +386,14 @@
             "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v2/\$(project_id)s" \
             "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v2/\$(project_id)s" \
             "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v2/\$(project_id)s"
+
+        get_or_create_service "cinderv3" "volumev3" "Cinder Volume Service V3"
+        get_or_create_endpoint \
+            "volumev3" \
+            "$REGION_NAME" \
+            "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v3/\$(project_id)s" \
+            "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v3/\$(project_id)s" \
+            "$CINDER_SERVICE_PROTOCOL://$CINDER_SERVICE_HOST:$CINDER_SERVICE_PORT/v3/\$(project_id)s"
     fi
 }
 
@@ -407,7 +415,7 @@
         recreate_database cinder
 
         # Migrate cinder database
-        $CINDER_BIN_DIR/cinder-manage db sync
+        $CINDER_BIN_DIR/cinder-manage --config-file $CINDER_CONF db sync
     fi
 
     if is_service_enabled c-vol && [[ -n "$CINDER_ENABLED_BACKENDS" ]]; then
@@ -552,7 +560,7 @@
         local be be_name
         for be in ${CINDER_ENABLED_BACKENDS//,/ }; do
             be_name=${be##*:}
-            openstack volume type create --property volume_backend_name="${be_name}" ${be_name}
+            openstack --os-region-name="$REGION_NAME" volume type create --property volume_backend_name="${be_name}" ${be_name}
         done
     fi
 }
diff --git a/lib/dlm b/lib/dlm
index 74eb67e..e391535 100644
--- a/lib/dlm
+++ b/lib/dlm
@@ -93,6 +93,8 @@
     if is_dlm_enabled; then
         if is_ubuntu; then
             install_package zookeeperd
+        elif is_fedora; then
+            install_package zookeeper
         else
             die $LINENO "Don't know how to install zookeeper on this platform"
         fi
diff --git a/lib/glance b/lib/glance
index 3743e16..887a14d 100644
--- a/lib/glance
+++ b/lib/glance
@@ -173,8 +173,8 @@
 
         iniset $GLANCE_SWIFT_STORE_CONF ref1 key $SERVICE_PASSWORD
         iniset $GLANCE_SWIFT_STORE_CONF ref1 auth_address $KEYSTONE_SERVICE_URI/v3
-        iniset $GLANCE_SWIFT_STORE_CONF ref1 user_domain_id default
-        iniset $GLANCE_SWIFT_STORE_CONF ref1 project_domain_id default
+        iniset $GLANCE_SWIFT_STORE_CONF ref1 user_domain_name $SERVICE_DOMAIN_NAME
+        iniset $GLANCE_SWIFT_STORE_CONF ref1 project_domain_name $SERVICE_DOMAIN_NAME
         iniset $GLANCE_SWIFT_STORE_CONF ref1 auth_version 3
 
         # commenting is not strictly necessary but it's confusing to have bad values in conf
@@ -288,11 +288,7 @@
 
         # required for swift access
         if is_service_enabled s-proxy; then
-
-            local glance_swift_user
-            glance_swift_user=$(get_or_create_user "glance-swift" \
-                "$SERVICE_PASSWORD" "default" "glance-swift@example.com")
-            get_or_add_user_project_role "ResellerAdmin" $glance_swift_user $SERVICE_PROJECT_NAME
+            create_service_user "glance-swift" "ResellerAdmin"
         fi
 
         get_or_create_service "glance" "image" "Glance Image Service"
@@ -338,10 +334,10 @@
     recreate_database glance
 
     # Migrate glance database
-    $GLANCE_BIN_DIR/glance-manage db_sync
+    $GLANCE_BIN_DIR/glance-manage --config-file $GLANCE_CONF_DIR/glance-api.conf db_sync
 
     # Load metadata definitions
-    $GLANCE_BIN_DIR/glance-manage db_load_metadefs
+    $GLANCE_BIN_DIR/glance-manage --config-file $GLANCE_CONF_DIR/glance-api.conf db_load_metadefs
 
     create_glance_cache_dir
 }
@@ -366,11 +362,6 @@
 
     git_clone $GLANCE_REPO $GLANCE_DIR $GLANCE_BRANCH
 
-    if is_service_enabled g-search; then
-        ${TOP_DIR}/pkg/elasticsearch.sh download
-        ${TOP_DIR}/pkg/elasticsearch.sh install
-    fi
-
     setup_develop $GLANCE_DIR
 }
 
@@ -390,7 +381,7 @@
         die $LINENO "g-api did not start"
     fi
 
-    #Start g-glare after g-reg/g-api/g-search
+    #Start g-glare after g-reg/g-api
     if is_service_enabled g-glare; then
         run_process g-glare "$GLANCE_BIN_DIR/glance-glare --config-file=$GLANCE_CONF_DIR/glance-glare.conf"
         echo "Waiting for Glare [g-glare] ($GLANCE_GLARE_HOSTPORT) to start..."
diff --git a/lib/heat b/lib/heat
index 4326321..730adad 100644
--- a/lib/heat
+++ b/lib/heat
@@ -241,7 +241,7 @@
     # (re)create heat database
     recreate_database heat
 
-    $HEAT_BIN_DIR/heat-manage db_sync
+    $HEAT_BIN_DIR/heat-manage --config-file $HEAT_CONF db_sync
     create_heat_cache_dir
 }
 
diff --git a/lib/keystone b/lib/keystone
index d830924..3309a91 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -106,9 +106,14 @@
 
 # Bind hosts
 KEYSTONE_ADMIN_BIND_HOST=${KEYSTONE_ADMIN_BIND_HOST:-$KEYSTONE_SERVICE_HOST}
-# Set the tenant for service accounts in Keystone
-SERVICE_TENANT_NAME=${SERVICE_TENANT_NAME:-service}
-SERVICE_PROJECT_NAME=${SERVICE_TENANT_NAME:-service}
+
+# Set the project for service accounts in Keystone
+SERVICE_DOMAIN_NAME=${SERVICE_DOMAIN_NAME:-Default}
+SERVICE_PROJECT_NAME=${SERVICE_PROJECT_NAME:-service}
+
+# Note 2016-03 : SERVICE_TENANT_NAME is kept for backwards
+# compatibility; we should be using SERVICE_PROJECT_NAME now
+SERVICE_TENANT_NAME=${SERVICE_PROJECT_NAME:-service}
 
 # if we are running with SSL use https protocols
 if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
@@ -329,13 +334,13 @@
     # Configure the project created by the 'keystone-manage bootstrap' as the cloud-admin project.
     # The users from this project are globally admin as before, but it also
     # allows policy changes in order to clarify the adminess scope.
-    iniset $KEYSTONE_CONF resource admin_project_domain_name default
+    iniset $KEYSTONE_CONF resource admin_project_domain_name Default
     iniset $KEYSTONE_CONF resource admin_project_name admin
 }
 
 # create_keystone_accounts() - Sets up common required keystone accounts
 
-# Tenant               User       Roles
+# Project              User       Roles
 # ------------------------------------------------------------------
 # admin                admin      admin
 # service              --         --
@@ -348,7 +353,7 @@
 # alt_demo             alt_demo   Member, anotherrole
 # invisible_to_admin   demo       Member
 
-# Group                Users            Roles                 Tenant
+# Group                Users            Roles                 Project
 # ------------------------------------------------------------------
 # admins               admin            admin                 admin
 # nonadmins            demo, alt_demo   Member, anotherrole   demo, alt_demo
@@ -360,8 +365,8 @@
     # The keystone bootstrapping process (performed via keystone-manage bootstrap)
     # creates an admin user, admin role and admin project. As a sanity check
     # we exercise the CLI to retrieve the IDs for these values.
-    local admin_tenant
-    admin_tenant=$(openstack project show "admin" -f value -c id)
+    local admin_project
+    admin_project=$(openstack project show "admin" -f value -c id)
     local admin_user
     admin_user=$(openstack user show "admin" -f value -c id)
     local admin_role
@@ -370,14 +375,15 @@
     get_or_add_user_domain_role $admin_role $admin_user default
 
     # Create service project/role
-    get_or_create_project "$SERVICE_PROJECT_NAME" default
+    get_or_create_domain "$SERVICE_DOMAIN_NAME"
+    get_or_create_project "$SERVICE_PROJECT_NAME" "$SERVICE_DOMAIN_NAME"
 
     # Service role, so service users do not have to be admins
     get_or_create_role service
 
     # The ResellerAdmin role is used by Nova and Ceilometer so we need to keep it.
-    # The admin role in swift allows a user to act as an admin for their tenant,
-    # but ResellerAdmin is needed for a user to act as any tenant. The name of this
+    # The admin role in swift allows a user to act as an admin for their project,
+    # but ResellerAdmin is needed for a user to act as any project. The name of this
     # role is also configurable in swift-proxy.conf
     get_or_create_role ResellerAdmin
 
@@ -390,32 +396,32 @@
     local another_role
     another_role=$(get_or_create_role "anotherrole")
 
-    # invisible tenant - admin can't see this one
-    local invis_tenant
-    invis_tenant=$(get_or_create_project "invisible_to_admin" default)
+    # invisible project - admin can't see this one
+    local invis_project
+    invis_project=$(get_or_create_project "invisible_to_admin" default)
 
     # demo
-    local demo_tenant
-    demo_tenant=$(get_or_create_project "demo" default)
+    local demo_project
+    demo_project=$(get_or_create_project "demo" default)
     local demo_user
     demo_user=$(get_or_create_user "demo" \
         "$ADMIN_PASSWORD" "default" "demo@example.com")
 
-    get_or_add_user_project_role $member_role $demo_user $demo_tenant
-    get_or_add_user_project_role $admin_role $admin_user $demo_tenant
-    get_or_add_user_project_role $another_role $demo_user $demo_tenant
-    get_or_add_user_project_role $member_role $demo_user $invis_tenant
+    get_or_add_user_project_role $member_role $demo_user $demo_project
+    get_or_add_user_project_role $admin_role $admin_user $demo_project
+    get_or_add_user_project_role $another_role $demo_user $demo_project
+    get_or_add_user_project_role $member_role $demo_user $invis_project
 
     # alt_demo
-    local alt_demo_tenant
-    alt_demo_tenant=$(get_or_create_project "alt_demo" default)
+    local alt_demo_project
+    alt_demo_project=$(get_or_create_project "alt_demo" default)
     local alt_demo_user
     alt_demo_user=$(get_or_create_user "alt_demo" \
         "$ADMIN_PASSWORD" "default" "alt_demo@example.com")
 
-    get_or_add_user_project_role $member_role $alt_demo_user $alt_demo_tenant
-    get_or_add_user_project_role $admin_role $admin_user $alt_demo_tenant
-    get_or_add_user_project_role $another_role $alt_demo_user $alt_demo_tenant
+    get_or_add_user_project_role $member_role $alt_demo_user $alt_demo_project
+    get_or_add_user_project_role $admin_role $admin_user $alt_demo_project
+    get_or_add_user_project_role $another_role $alt_demo_user $alt_demo_project
 
     # groups
     local admin_group
@@ -425,11 +431,11 @@
     non_admin_group=$(get_or_create_group "nonadmins" \
         "default" "non-admin group")
 
-    get_or_add_group_project_role $member_role $non_admin_group $demo_tenant
-    get_or_add_group_project_role $another_role $non_admin_group $demo_tenant
-    get_or_add_group_project_role $member_role $non_admin_group $alt_demo_tenant
-    get_or_add_group_project_role $another_role $non_admin_group $alt_demo_tenant
-    get_or_add_group_project_role $admin_role $admin_group $admin_tenant
+    get_or_add_group_project_role $member_role $non_admin_group $demo_project
+    get_or_add_group_project_role $another_role $non_admin_group $demo_project
+    get_or_add_group_project_role $member_role $non_admin_group $alt_demo_project
+    get_or_add_group_project_role $another_role $non_admin_group $alt_demo_project
+    get_or_add_group_project_role $admin_role $admin_group $admin_project
 }
 
 # Create a user that is capable of verifying keystone tokens for use with auth_token middleware.
@@ -442,9 +448,8 @@
 function create_service_user {
     local role=${2:-service}
 
-    local user
-    user=$(get_or_create_user "$1" "$SERVICE_PASSWORD" default)
-    get_or_add_user_project_role "$role" "$user" "$SERVICE_PROJECT_NAME"
+    get_or_create_user "$1" "$SERVICE_PASSWORD" "$SERVICE_DOMAIN_NAME"
+    get_or_add_user_project_role "$role" "$1" "$SERVICE_PROJECT_NAME" "$SERVICE_DOMAIN_NAME" "$SERVICE_DOMAIN_NAME"
 }
 
 # Configure the service to use the auth token middleware.
@@ -464,9 +469,9 @@
     iniset $conf_file $section auth_url $KEYSTONE_AUTH_URI
     iniset $conf_file $section username $admin_user
     iniset $conf_file $section password $SERVICE_PASSWORD
-    iniset $conf_file $section user_domain_id default
+    iniset $conf_file $section user_domain_name "$SERVICE_DOMAIN_NAME"
     iniset $conf_file $section project_name $SERVICE_PROJECT_NAME
-    iniset $conf_file $section project_domain_id default
+    iniset $conf_file $section project_domain_name "$SERVICE_DOMAIN_NAME"
 
     iniset $conf_file $section auth_uri $KEYSTONE_SERVICE_URI
     iniset $conf_file $section cafile $SSL_BUNDLE_FILE
@@ -484,16 +489,16 @@
     recreate_database keystone
 
     # Initialize keystone database
-    $KEYSTONE_BIN_DIR/keystone-manage db_sync
+    $KEYSTONE_BIN_DIR/keystone-manage --config-file $KEYSTONE_CONF db_sync
 
     if [[ "$KEYSTONE_TOKEN_FORMAT" == "pki" || "$KEYSTONE_TOKEN_FORMAT" == "pkiz" ]]; then
         # Set up certificates
         rm -rf $KEYSTONE_CONF_DIR/ssl
-        $KEYSTONE_BIN_DIR/keystone-manage pki_setup
+        $KEYSTONE_BIN_DIR/keystone-manage --config-file $KEYSTONE_CONF pki_setup
     fi
     if [[ "$KEYSTONE_TOKEN_FORMAT" == "fernet" ]]; then
         rm -rf "$KEYSTONE_CONF_DIR/fernet-keys/"
-        $KEYSTONE_BIN_DIR/keystone-manage fernet_setup
+        $KEYSTONE_BIN_DIR/keystone-manage --config-file $KEYSTONE_CONF fernet_setup
     fi
 }
 
@@ -619,9 +624,9 @@
         --bootstrap-role-name admin \
         --bootstrap-service-name keystone \
         --bootstrap-region-id "$REGION_NAME" \
-        --bootstrap-admin-url "$KEYSTONE_AUTH_URI/v$IDENTITY_API_VERSION" \
-        --bootstrap-public-url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION" \
-        --bootstrap-internal-url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v$IDENTITY_API_VERSION"
+        --bootstrap-admin-url "$KEYSTONE_AUTH_URI" \
+        --bootstrap-public-url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT" \
+        --bootstrap-internal-url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT"
 }
 
 # Restore xtrace
diff --git a/lib/neutron b/lib/neutron
new file mode 100644
index 0000000..e141583
--- /dev/null
+++ b/lib/neutron
@@ -0,0 +1,558 @@
+#!/bin/bash
+#
+# lib/neutron
+# Install and start **Neutron** network services
+
+# Dependencies:
+#
+# ``functions`` file
+# ``DEST`` must be defined
+
+# ``stack.sh`` calls the entry points in this order:
+#
+# - is_XXXX_enabled
+# - install_XXXX
+# - configure_XXXX
+# - init_XXXX
+# - start_XXXX
+# - stop_XXXX
+# - cleanup_XXXX
+
+# Save trace setting
+XTRACE=$(set +o | grep xtrace)
+set +o xtrace
+
+# Defaults
+# --------
+
+# Set up default directories
+GITDIR["python-neutronclient"]=$DEST/python-neutronclient
+
+NEUTRON_AGENT=${NEUTRON_AGENT:-openvswitch}
+NEUTRON_DIR=$DEST/neutron
+NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron}
+
+NEUTRON_BIN_DIR=$(get_python_exec_prefix)
+NEUTRON_DHCP_BINARY="neutron-dhcp-agent"
+
+NEUTRON_CONF_DIR=/etc/neutron
+NEUTRON_CONF=$NEUTRON_CONF_DIR/neutron.conf
+NEUTRON_META_CONF=$NEUTRON_CONF_DIR/metadata_agent.ini
+
+NEUTRON_DHCP_CONF=$NEUTRON_CONF_DIR/dhcp_agent.ini
+NEUTRON_L3_CONF=$NEUTRON_CONF_DIR/l3_agent.ini
+NEUTRON_AGENT_CONF=$NEUTRON_CONF_DIR/
+
+NEUTRON_STATE_PATH=${NEUTRON_STATE_PATH:=$DATA_DIR/neutron}
+NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron}
+
+# By default, use the ML2 plugin
+NEUTRON_PLUGIN=${NEUTRON_PLUGIN:-ml2}
+NEUTRON_PLUGIN_CONF_FILENAME=${NEUTRON_PLUGIN_CONF_FILENAME:-ml2_conf.ini}
+NEUTRON_PLUGIN_CONF_PATH=$NEUTRON_CONF_DIR/plugins/$NEUTRON_PLUGIN
+NEUTRON_PLUGIN_CONF=$NEUTRON_PLUGIN_CONF_PATH/$NEUTRON_PLUGIN_CONF_FILENAME
+
+NEUTRON_AGENT_BINARY=${NEUTRON_AGENT_BINARY:-neutron-$NEUTRON_AGENT-agent}
+NEUTRON_L3_BINARY=${NEUTRON_L3_BINARY:-neutron-l3-agent}
+NEUTRON_META_BINARY=${NEUTRON_META_BINARY:-neutron-metadata-agent}
+
+# Public facing bits
+if is_ssl_enabled_service "neutron" || is_service_enabled tls-proxy; then
+    NEUTRON_SERVICE_PROTOCOL="https"
+fi
+NEUTRON_SERVICE_HOST=${NEUTRON_SERVICE_HOST:-$SERVICE_HOST}
+NEUTRON_SERVICE_PORT=${NEUTRON_SERVICE_PORT:-9696}
+NEUTRON_SERVICE_PORT_INT=${NEUTRON_SERVICE_PORT_INT:-19696}
+NEUTRON_SERVICE_PROTOCOL=${NEUTRON_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
+
+NEUTRON_AUTH_STRATEGY=${NEUTRON_AUTH_STRATEGY:-keystone}
+NEUTRON_ROOTWRAP=$(get_rootwrap_location neutron)
+NEUTRON_ROOTWRAP_CONF_FILE=$NEUTRON_CONF_DIR/rootwrap.conf
+NEUTRON_ROOTWRAP_DAEMON_CMD="sudo $NEUTRON_ROOTWRAP-daemon $NEUTRON_ROOTWRAP_CONF_FILE"
+
+# Add all enabled config files to a single config arg
+NEUTRON_CONFIG_ARG=${NEUTRON_CONFIG_ARG:-""}
+
+# Functions
+# ---------
+
+# Test if any Neutron services are enabled
+# is_neutron_enabled
+function is_neutron_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"neutron-" || ,${ENABLED_SERVICES} =~ ,"q-" ]] && return 0
+    return 1
+}
+
+# Test if any Neutron services are enabled
+# is_neutron_enabled
+function is_neutron_legacy_enabled {
+    [[ ,${ENABLED_SERVICES} =~ ,"q-" ]] && return 0
+    return 1
+}
+
+# cleanup_neutron() - Remove residual data files, anything left over from previous
+# runs that a clean run would need to clean up
+function cleanup_neutron_new {
+    source $TOP_DIR/lib/neutron_plugins/${NEUTRON_AGENT}_agent
+    if is_neutron_ovs_base_plugin; then
+        neutron_ovs_base_cleanup
+    fi
+
+    if [[ $NEUTRON_AGENT == "linuxbridge" ]]; then
+        neutron_lb_cleanup
+    fi
+    # delete all namespaces created by neutron
+    for ns in $(sudo ip netns list | grep -o -E '(qdhcp|qrouter|qlbaas|fip|snat)-[0-9a-f-]*'); do
+        sudo ip netns delete ${ns}
+    done
+}
+
+# configure_neutron() - Set config files, create data dirs, etc
+function configure_neutron_new {
+    sudo install -d -o $STACK_USER $NEUTRON_CONF_DIR
+
+    (cd $NEUTRON_DIR && exec ./tools/generate_config_file_samples.sh)
+
+    cp $NEUTRON_DIR/etc/neutron.conf.sample $NEUTRON_CONF
+
+    configure_neutron_rootwrap
+
+    mkdir -p $NEUTRON_PLUGIN_CONF_PATH
+
+    cp $NEUTRON_DIR/etc/neutron/plugins/$NEUTRON_PLUGIN/$NEUTRON_PLUGIN_CONF_FILENAME.sample $NEUTRON_PLUGIN_CONF
+
+    iniset $NEUTRON_CONF database connection `database_connection_url neutron`
+    iniset $NEUTRON_CONF DEFAULT state_path $NEUTRON_STATE_PATH
+    iniset $NEUTRON_CONF oslo_concurrency lock_path $NEUTRON_STATE_PATH/lock
+    iniset $NEUTRON_CONF DEFAULT use_syslog $SYSLOG
+
+    iniset_rpc_backend neutron $NEUTRON_CONF
+
+    # Neutron API server & Neutron plugin
+    if is_service_enabled neutron-api; then
+        local policy_file=$NEUTRON_CONF_DIR/policy.json
+        cp $NEUTRON_DIR/etc/policy.json $policy_file
+        # Allow neutron user to administer neutron to match neutron account
+        sed -i 's/"context_is_admin":  "role:admin"/"context_is_admin":  "role:admin or user_name:neutron"/g' $policy_file
+
+        cp $NEUTRON_DIR/etc/api-paste.ini $NEUTRON_CONF_DIR/api-paste.ini
+
+        iniset $NEUTRON_CONF DEFAULT core_plugin ml2
+
+        iniset $NEUTRON_CONF DEFAULT verbose True
+        iniset $NEUTRON_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
+        iniset $NEUTRON_CONF DEFAULT policy_file $policy_file
+        iniset $NEUTRON_CONF DEFAULT allow_overlapping_ips True
+
+        iniset $NEUTRON_CONF DEFAULT auth_strategy $NEUTRON_AUTH_STRATEGY
+        configure_auth_token_middleware $NEUTRON_CONF neutron $NEUTRON_AUTH_CACHE_DIR keystone_authtoken
+
+        # Configuration for neutron notifations 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
+
+        iniset $NEUTRON_CONF nova auth_type password
+        iniset $NEUTRON_CONF nova auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v3"
+        iniset $NEUTRON_CONF nova username nova
+        iniset $NEUTRON_CONF nova password $SERVICE_PASSWORD
+        iniset $NEUTRON_CONF nova user_domain_id default
+        iniset $NEUTRON_CONF nova project_name $SERVICE_TENANT_NAME
+        iniset $NEUTRON_CONF nova project_domain_id default
+        iniset $NEUTRON_CONF nova region_name $REGION_NAME
+
+        # Configure VXLAN
+        # TODO(sc68cal) not hardcode?
+        iniset $NEUTRON_PLUGIN_CONF ml2 tenant_network_types vxlan
+        iniset $NEUTRON_PLUGIN_CONF ml2 type_drivers vxlan
+        iniset $NEUTRON_PLUGIN_CONF ml2 mechanism_drivers openvswitch,linuxbridge
+        iniset $NEUTRON_PLUGIN_CONF ml2_type_vxlan vni_ranges 1001:2000
+    fi
+
+    # Neutron OVS or LB agent
+    if is_service_enabled neutron-agent; then
+        iniset $NEUTRON_PLUGIN_CONF agent tunnel_types vxlan
+
+        # Configure the neutron agent
+        if [[ $NEUTRON_AGENT == "linuxbridge" ]]; then
+            iniset $NEUTRON_PLUGIN_CONF securitygroup iptables
+            iniset $NEUTRON_PLUGIN_CONF vxlan local_ip $HOST_IP
+        else
+            iniset $NEUTRON_PLUGIN_CONF securitygroup iptables_hybrid
+            iniset $NEUTRON_PLUGIN_CONF ovs local_ip $HOST_IP
+        fi
+    fi
+
+    # DHCP Agent
+    if is_service_enabled neutron-dhcp; then
+        cp $NEUTRON_DIR/etc/dhcp_agent.ini.sample $NEUTRON_DHCP_CONF
+
+        iniset $NEUTRON_DHCP_CONF DEFAULT verbose True
+        iniset $NEUTRON_DHCP_CONF DEFAULT debug True
+        iniset $NEUTRON_DHCP_CONF agent root_helper_daemon "$NEUTRON_ROOTWRAP_DAEMON_CMD"
+        iniset $NEUTRON_DHCP_CONF DEFAULT interface_driver $NEUTRON_AGENT
+        neutron_plugin_configure_dhcp_agent $NEUTRON_DHCP_CONF
+    fi
+
+    if is_service_enabled neutron-l3; then
+        cp $NEUTRON_DIR/etc/l3_agent.ini.sample $NEUTRON_L3_CONF
+        iniset $NEUTRON_L3_CONF DEFAULT interface_driver $NEUTRON_AGENT
+        iniset $NEUTRON_CONF DEFAULT service_plugins router
+        iniset $NEUTRON_L3_CONF agent root_helper_daemon "$NEUTRON_ROOTWRAP_DAEMON_CMD"
+        iniset $NEUTRON_L3_CONF DEFAULT debug True
+        iniset $NEUTRON_L3_CONF DEFAULT verbose True
+        neutron_plugin_configure_l3_agent $NEUTRON_L3_CONF
+    fi
+
+    # Metadata
+    if is_service_enabled neutron-metadata-agent; then
+        cp $NEUTRON_DIR/etc/metadata_agent.ini.sample $NEUTRON_META_CONF
+
+        iniset $NEUTRON_META_CONF DEFAULT verbose True
+        iniset $NEUTRON_META_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
+        iniset $NEUTRON_META_CONF DEFAULT nova_metadata_ip $SERVICE_HOST
+        iniset $NEUTRON_META_CONF agent root_helper_daemon "$NEUTRON_ROOTWRAP_DAEMON_CMD"
+
+        # TODO(dtroyer): remove the v2.0 hard code below
+        iniset $NEUTRON_META_CONF DEFAULT auth_url $KEYSTONE_SERVICE_URI/v2.0
+        configure_auth_token_middleware $NEUTRON_META_CONF neutron $NEUTRON_AUTH_CACHE_DIR DEFAULT
+    fi
+
+    # Format logging
+    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
+        setup_colorized_logging $NEUTRON_CONF DEFAULT project_id
+    else
+        # Show user_name and project_name by default
+        iniset $NEUTRON_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s] %(instance)s%(message)s"
+    fi
+
+    if is_service_enabled tls-proxy; then
+        # Set the service port for a proxy to take the original
+        iniset $NEUTRON_CONF DEFAULT bind_port "$NEUTRON_SERVICE_PORT_INT"
+    fi
+
+    if is_ssl_enabled_service "nova"; then
+        iniset $NEUTRON_CONF nova cafile $SSL_BUNDLE_FILE
+    fi
+
+    if is_ssl_enabled_service "neutron"; then
+        ensure_certificates NEUTRON
+
+        iniset $NEUTRON_CONF DEFAULT use_ssl True
+        iniset $NEUTRON_CONF DEFAULT ssl_cert_file "$NEUTRON_SSL_CERT"
+        iniset $NEUTRON_CONF DEFAULT ssl_key_file "$NEUTRON_SSL_KEY"
+    fi
+
+}
+
+# configure_neutron_rootwrap() - configure Neutron's rootwrap
+function configure_neutron_rootwrap {
+    # Set the paths of certain binaries
+    neutron_rootwrap=$(get_rootwrap_location neutron)
+
+    # Specify ``rootwrap.conf`` as first parameter to neutron-rootwrap
+    local rootwrap_sudoer_cmd="${neutron_rootwrap} $NEUTRON_CONF_DIR/rootwrap.conf"
+
+    # Deploy new rootwrap filters files (owned by root).
+    # Wipe any existing rootwrap.d files first
+    if [[ -d $NEUTRON_CONF_DIR/rootwrap.d ]]; then
+        sudo rm -rf $NEUTRON_CONF_DIR/rootwrap.d
+    fi
+
+    # Deploy filters to /etc/neutron/rootwrap.d
+    sudo install -d -o root -g root -m 755 $NEUTRON_CONF_DIR/rootwrap.d
+    sudo install -o root -g root -m 644 $NEUTRON_DIR/etc/neutron/rootwrap.d/*.filters $NEUTRON_CONF_DIR/rootwrap.d
+
+    # Set up ``rootwrap.conf``, pointing to ``$NEUTRON_CONF_DIR/rootwrap.d``
+    sudo install -o root -g root -m 644 $NEUTRON_DIR/etc/rootwrap.conf $NEUTRON_CONF_DIR
+    sudo sed -e "s:^filters_path=.*$:filters_path=$NEUTRON_CONF_DIR/rootwrap.d:" -i $NEUTRON_CONF_DIR/rootwrap.conf
+
+    # Set up the rootwrap sudoers for Neutron
+    tempfile=`mktemp`
+    echo "$STACK_USER ALL=(root) NOPASSWD: $rootwrap_sudoer_cmd *" >$tempfile
+    chmod 0440 $tempfile
+    sudo chown root:root $tempfile
+    sudo mv $tempfile /etc/sudoers.d/neutron-rootwrap
+}
+
+# Make Neutron-required changes to nova.conf
+function configure_neutron_nova_new {
+    iniset $NOVA_CONF DEFAULT use_neutron True
+    iniset $NOVA_CONF neutron auth_type "password"
+    iniset $NOVA_CONF neutron auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v3"
+    iniset $NOVA_CONF neutron username neutron
+    iniset $NOVA_CONF neutron password "$SERVICE_PASSWORD"
+    iniset $NOVA_CONF neutron user_domain_name "Default"
+    iniset $NOVA_CONF neutron project_name "$SERVICE_TENANT_NAME"
+    iniset $NOVA_CONF neutron project_domain_name "Default"
+    iniset $NOVA_CONF neutron auth_strategy $NEUTRON_AUTH_STRATEGY
+    iniset $NOVA_CONF neutron region_name "$REGION_NAME"
+    iniset $NOVA_CONF neutron url $NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT
+
+    iniset $NOVA_CONF DEFAULT firewall_driver nova.virt.firewall.NoopFirewallDriver
+
+    if is_service_enabled neutron-metadata-agent; then
+        iniset $NOVA_CONF neutron service_metadata_proxy "True"
+    fi
+
+}
+
+# Tenant               User       Roles
+# ------------------------------------------------------------------
+# service              neutron    admin        # if enabled
+
+# create_neutron_accounts() - Create required service accounts
+function create_neutron_accounts_new {
+    if [[ "$ENABLED_SERVICES" =~ "neutron-api" ]]; then
+
+        create_service_user "neutron"
+
+        neutron_service=$(get_or_create_service "neutron" \
+            "network" "Neutron Service")
+        get_or_create_endpoint $neutron_service \
+            "$REGION_NAME" \
+            "$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/" \
+            "$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/" \
+            "$NEUTRON_SERVICE_PROTOCOL://$NEUTRON_SERVICE_HOST:$NEUTRON_SERVICE_PORT/"
+    fi
+}
+
+# create_neutron_cache_dir() - Part of the init_neutron() process
+function create_neutron_cache_dir {
+    # Create cache dir
+    sudo install -d -o $STACK_USER $NEUTRON_AUTH_CACHE_DIR
+    rm -f $NEUTRON_AUTH_CACHE_DIR/*
+}
+
+# init_neutron() - Initialize databases, etc.
+function init_neutron_new {
+
+    recreate_database neutron
+
+    # Run Neutron db migrations
+    $NEUTRON_BIN_DIR/neutron-db-manage $NEUTRON_CONFIG_ARG upgrade heads
+
+    create_neutron_cache_dir
+}
+
+# install_neutron() - Collect source and prepare
+function install_neutron_new {
+    git_clone $NEUTRON_REPO $NEUTRON_DIR $NEUTRON_BRANCH
+    setup_develop $NEUTRON_DIR
+
+    # Install neutron-lib from git so we make sure we're testing
+    # the latest code.
+    if use_library_from_git "neutron-lib"; then
+        git_clone_by_name "neutron-lib"
+        setup_dev_lib "neutron-lib"
+    fi
+
+    # L3 service requires radvd
+    if is_service_enabled neutron-l3; then
+        install_package radvd
+    fi
+
+    if is_service_enabled neutron-agent neutron-dhcp neutron-l3; then
+        #TODO(sc68cal) - kind of ugly
+        source $TOP_DIR/lib/neutron_plugins/${NEUTRON_AGENT}_agent
+        neutron_plugin_install_agent_packages
+    fi
+
+}
+
+# install_neutronclient() - Collect source and prepare
+function install_neutronclient {
+    if use_library_from_git "python-neutronclient"; then
+        git_clone_by_name "python-neutronclient"
+        setup_dev_lib "python-neutronclient"
+        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-neutronclient"]}/tools/,/etc/bash_completion.d/}neutron.bash_completion
+    fi
+}
+
+# start_neutron_api() - Start the API process ahead of other things
+function start_neutron_api {
+    local service_port=$NEUTRON_SERVICE_PORT
+    local service_protocol=$NEUTRON_SERVICE_PROTOCOL
+    if is_service_enabled tls-proxy; then
+        service_port=$NEUTRON_SERVICE_PORT_INT
+        service_protocol="http"
+    fi
+
+    # Start the Neutron service
+    # TODO(sc68cal) Stop hard coding this
+    run_process neutron-api "$NEUTRON_BIN_DIR/neutron-server --config-file $NEUTRON_CONF --config-file $NEUTRON_PLUGIN_CONF"
+
+    if is_ssl_enabled_service "neutron"; then
+        ssl_ca="--ca-certificate=${SSL_BUNDLE_FILE}"
+        local testcmd="wget ${ssl_ca} --no-proxy -q -O- $service_protocol://$NEUTRON_SERVICE_HOST:$service_port"
+        test_with_retry "$testcmd" "Neutron did not start" $SERVICE_TIMEOUT
+    else
+        if ! wait_for_service $SERVICE_TIMEOUT $service_protocol://$NEUTRON_SERVICE_HOST:$service_port; then
+            die $LINENO "neutron-api did not start"
+        fi
+    fi
+
+
+    # Start proxy if enabled
+    if is_service_enabled tls-proxy; then
+        start_tls_proxy '*' $NEUTRON_SERVICE_PORT $NEUTRON_SERVICE_HOST $NEUTRON_SERVICE_PORT_INT &
+    fi
+}
+
+# start_neutron() - Start running processes, including screen
+function start_neutron_new {
+    _set_config_files
+
+    # Start up the neutron agents if enabled
+    # TODO(sc68cal) Make this pluggable so different DevStack plugins for different Neutron plugins
+    # can resolve the $NEUTRON_AGENT_BINARY
+    if is_service_enabled neutron-agent; then
+        run_process neutron-agent "$NEUTRON_BIN_DIR/$NEUTRON_AGENT_BINARY $NEUTRON_CONFIG_ARG"
+    fi
+    if is_service_enabled neutron-dhcp; then
+        neutron_plugin_configure_dhcp_agent $NEUTRON_DHCP_CONF
+        run_process neutron-dhcp "$NEUTRON_BIN_DIR/$NEUTRON_DHCP_BINARY $NEUTRON_CONFIG_ARG"
+    fi
+    if is_service_enabled neutron-l3; then
+        run_process neutron-l3 "$NEUTRON_BIN_DIR/$NEUTRON_L3_BINARY $NEUTRON_CONFIG_ARG"
+        # XXX(sc68cal) - Here's where plugins can wire up their own networks instead
+        # of the code in lib/neutron_plugins/services/l3
+        if type -p neutron_plugin_create_initial_networks > /dev/null; then
+            neutron_plugin_create_initial_networks
+        else
+            # XXX(sc68cal) Load up the built in Neutron networking code and build a topology
+            source $TOP_DIR/lib/neutron_plugins/services/l3
+            # Create the networks using servic
+            create_neutron_initial_network
+        fi
+    fi
+    if is_service_enabled neutron-metadata-agent; then
+        run_process neutron-metadata-agent "$NEUTRON_BIN_DIR/$NEUTRON_META_BINARY $NEUTRON_CONFIG_ARG"
+    fi
+}
+
+# stop_neutron() - Stop running processes (non-screen)
+function stop_neutron_new {
+    for serv in neutron-api neutron-agent neutron-l3; do
+        stop_process $serv
+    done
+
+    if is_service_enabled neutron-dhcp; then
+        stop_process neutron-dhcp
+        pid=$(ps aux | awk '/[d]nsmasq.+interface=(tap|ns-)/ { print $2 }')
+        [ ! -z "$pid" ] && sudo kill -9 $pid
+    fi
+
+    if is_service_enabled neutron-metadata-agent; then
+        sudo pkill -9 -f neutron-ns-metadata-proxy || :
+        stop_process neutron-metadata-agent
+    fi
+}
+
+# Compile the lost of enabled config files
+function _set_config_files {
+
+    #TODO(sc68cal) - see if we can clean up this and only
+    # pass in config files that make sense for certain agents
+    if is_service_enabled neutron-api; then
+        NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_CONF"
+    fi
+
+    #TODO(sc68cal) OVS and LB agent uses settings in NEUTRON_PLUGIN_CONF (ml2_conf.ini) but others may not
+    if is_service_enabled neutron-agent; then
+        NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_PLUGIN_CONF"
+    fi
+
+    if is_service_enabled neutron-dhcp; then
+        NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_DHCP_CONF"
+    fi
+
+    if is_service_enabled neutron-l3; then
+        NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_L3_CONF"
+    fi
+
+    if is_service_enabled neutron-metadata-agent; then
+        NEUTRON_CONFIG_ARG+=" --config-file $NEUTRON_META_CONF"
+    fi
+
+}
+
+# Dispatch functions
+# These are needed for compatibility between the old and new implementations
+# where there are function name overlaps.  These will be removed when
+# neutron-legacy is removed.
+# TODO(sc68cal) Remove when neutron-legacy is no more.
+function cleanup_neutron {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        cleanup_mutnauq "$@"
+    else
+        cleanup_neutron_new "$@"
+    fi
+}
+
+function configure_neutron {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        configure_mutnauq "$@"
+    else
+        configure_neutron_new "$@"
+    fi
+}
+
+function configure_neutron_nova {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        create_nova_conf_neutron "$@"
+    else
+        configure_neutron_nova_new "$@"
+    fi
+}
+
+function create_neutron_accounts {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        create_mutnauq_accounts "$@"
+    else
+        create_neutron_accounts_new "$@"
+    fi
+}
+
+function init_neutron {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        init_mutnauq "$@"
+    else
+        init_neutron_new "$@"
+    fi
+}
+
+function install_neutron {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        install_mutnauq "$@"
+    else
+        install_neutron_new "$@"
+    fi
+}
+
+function start_neutron {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        start_mutnauq_l2_agent "$@"
+        start_mutnauq_other_agents "$@"
+    else
+        start_neutron_new "$@"
+    fi
+}
+
+function stop_neutron {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        stop_mutnauq "$@"
+    else
+        stop_neutron_new "$@"
+    fi
+}
+
+# Restore xtrace
+$XTRACE
diff --git a/lib/neutron-legacy b/lib/neutron-legacy
index 3ed690c..a3a0dcc 100644
--- a/lib/neutron-legacy
+++ b/lib/neutron-legacy
@@ -61,45 +61,12 @@
 # Neutron Network Configuration
 # -----------------------------
 
-# Subnet IP version
-IP_VERSION=${IP_VERSION:-"4+6"}
-# Validate IP_VERSION
-if [[ $IP_VERSION != "4" ]] && [[ $IP_VERSION != "6" ]] && [[ $IP_VERSION != "4+6" ]]; then
-    die $LINENO "IP_VERSION must be either 4, 6, or 4+6"
-fi
-# Gateway and subnet defaults, in case they are not customized in localrc
-NETWORK_GATEWAY=${NETWORK_GATEWAY:-10.0.0.1}
-PUBLIC_NETWORK_GATEWAY=${PUBLIC_NETWORK_GATEWAY:-172.24.4.1}
-PRIVATE_SUBNET_NAME=${PRIVATE_SUBNET_NAME:-"private-subnet"}
-PUBLIC_SUBNET_NAME=${PUBLIC_SUBNET_NAME:-"public-subnet"}
-
-# Subnetpool defaults
-SUBNETPOOL_NAME=${SUBNETPOOL_NAME:-"shared-default-subnetpool"}
-
-SUBNETPOOL_PREFIX_V4=${SUBNETPOOL_PREFIX_V4:-10.0.0.0/8}
-SUBNETPOOL_PREFIX_V6=${SUBNETPOOL_PREFIX_V6:-2001:db8:8000::/48}
-
-SUBNETPOOL_SIZE_V4=${SUBNETPOOL_SIZE_V4:-24}
-SUBNETPOOL_SIZE_V6=${SUBNETPOOL_SIZE_V6:-64}
-
+deprecated "Using lib/neutron-legacy is deprecated, and it will be removed in the future"
 
 if is_ssl_enabled_service "neutron" || is_service_enabled tls-proxy; then
     Q_PROTOCOL="https"
 fi
 
-# Generate 40-bit IPv6 Global ID to comply with RFC 4193
-IPV6_GLOBAL_ID=`uuidgen | sed s/-//g | cut -c 23- | sed -e "s/\(..\)\(....\)\(....\)/\1:\2:\3/"`
-
-# IPv6 gateway and subnet defaults, in case they are not customized in localrc
-IPV6_RA_MODE=${IPV6_RA_MODE:-slaac}
-IPV6_ADDRESS_MODE=${IPV6_ADDRESS_MODE:-slaac}
-IPV6_PUBLIC_SUBNET_NAME=${IPV6_PUBLIC_SUBNET_NAME:-ipv6-public-subnet}
-IPV6_PRIVATE_SUBNET_NAME=${IPV6_PRIVATE_SUBNET_NAME:-ipv6-private-subnet}
-FIXED_RANGE_V6=${FIXED_RANGE_V6:-fd$IPV6_GLOBAL_ID::/64}
-IPV6_PRIVATE_NETWORK_GATEWAY=${IPV6_PRIVATE_NETWORK_GATEWAY:-fd$IPV6_GLOBAL_ID::1}
-IPV6_PUBLIC_RANGE=${IPV6_PUBLIC_RANGE:-2001:db8::/64}
-IPV6_PUBLIC_NETWORK_GATEWAY=${IPV6_PUBLIC_NETWORK_GATEWAY:-2001:db8::2}
-IPV6_ROUTER_GW_IP=${IPV6_ROUTER_GW_IP:-2001:db8::1}
 
 # Set up default directories
 GITDIR["python-neutronclient"]=$DEST/python-neutronclient
@@ -108,7 +75,6 @@
 NEUTRON_DIR=$DEST/neutron
 NEUTRON_FWAAS_DIR=$DEST/neutron-fwaas
 NEUTRON_LBAAS_DIR=$DEST/neutron-lbaas
-NEUTRON_VPNAAS_DIR=$DEST/neutron-vpnaas
 NEUTRON_AUTH_CACHE_DIR=${NEUTRON_AUTH_CACHE_DIR:-/var/cache/neutron}
 
 # Support entry points installation of console scripts
@@ -125,9 +91,6 @@
 # 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"
@@ -139,7 +102,6 @@
 Q_DHCP_CONF_FILE=$NEUTRON_CONF_DIR/dhcp_agent.ini
 Q_L3_CONF_FILE=$NEUTRON_CONF_DIR/l3_agent.ini
 Q_FWAAS_CONF_FILE=$NEUTRON_CONF_DIR/fwaas_driver.ini
-Q_VPN_CONF_FILE=$NEUTRON_CONF_DIR/vpn_agent.ini
 Q_META_CONF_FILE=$NEUTRON_CONF_DIR/metadata_agent.ini
 
 # Default name for Neutron database
@@ -176,65 +138,11 @@
 Q_NOTIFY_NOVA_PORT_DATA_CHANGES=${Q_NOTIFY_NOVA_PORT_DATA_CHANGES:-True}
 VIF_PLUGGING_IS_FATAL=${VIF_PLUGGING_IS_FATAL:-True}
 VIF_PLUGGING_TIMEOUT=${VIF_PLUGGING_TIMEOUT:-300}
-# Specify if the initial private and external networks should be created
-NEUTRON_CREATE_INITIAL_NETWORKS=${NEUTRON_CREATE_INITIAL_NETWORKS:-True}
-
-## Provider Network Information
-PROVIDER_SUBNET_NAME=${PROVIDER_SUBNET_NAME:-"provider_net"}
-IPV6_PROVIDER_SUBNET_NAME=${IPV6_PROVIDER_SUBNET_NAME:-"provider_net_v6"}
-IPV6_PROVIDER_FIXED_RANGE=${IPV6_PROVIDER_FIXED_RANGE:-}
-IPV6_PROVIDER_NETWORK_GATEWAY=${IPV6_PROVIDER_NETWORK_GATEWAY:-}
-
-# Define the public bridge that will transmit traffic from VMs to the
-# physical network - used by both the OVS and Linux Bridge drivers.
-PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex}
-
-# Use flat providernet for public network
-#
-# If Q_USE_PROVIDERNET_FOR_PUBLIC=True, use a flat provider network
-# for external interface of neutron l3-agent.  In that case,
-# PUBLIC_PHYSICAL_NETWORK specifies provider:physical_network value
-# used for the network.  In case of ofagent, you should add the
-# corresponding entry to your OFAGENT_PHYSICAL_INTERFACE_MAPPINGS.
-# For openvswitch agent, you should add the corresponding entry to
-# your OVS_BRIDGE_MAPPINGS.
-#
-# eg.  (ofagent)
-#    Q_USE_PROVIDERNET_FOR_PUBLIC=True
-#    Q_USE_PUBLIC_VETH=True
-#    PUBLIC_PHYSICAL_NETWORK=public
-#    OFAGENT_PHYSICAL_INTERFACE_MAPPINGS=public:veth-pub-int
-#
-# eg.  (openvswitch agent)
-#    Q_USE_PROVIDERNET_FOR_PUBLIC=True
-#    PUBLIC_PHYSICAL_NETWORK=public
-#    OVS_BRIDGE_MAPPINGS=public:br-ex
-Q_USE_PROVIDERNET_FOR_PUBLIC=${Q_USE_PROVIDERNET_FOR_PUBLIC:-False}
-PUBLIC_PHYSICAL_NETWORK=${PUBLIC_PHYSICAL_NETWORK:-public}
-
-# If Q_USE_PUBLIC_VETH=True, create and use a veth pair instead of
-# PUBLIC_BRIDGE.  This is intended to be used with
-# Q_USE_PROVIDERNET_FOR_PUBLIC=True.
-Q_USE_PUBLIC_VETH=${Q_USE_PUBLIC_VETH:-False}
-Q_PUBLIC_VETH_EX=${Q_PUBLIC_VETH_EX:-veth-pub-ex}
-Q_PUBLIC_VETH_INT=${Q_PUBLIC_VETH_INT:-veth-pub-int}
-
-# The next two variables are configured by plugin
-# e.g.  _configure_neutron_l3_agent or lib/neutron_plugins/*
-#
-# 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:-True}
 
 # List of config file names in addition to the main plugin config file
 # See _configure_neutron_common() for details about setting it up
 declare -a Q_PLUGIN_EXTRA_CONF_FILES
 
-# List of (optional) config files for VPN device drivers to use with
-# the neutron-q-vpn agent
-declare -a Q_VPN_EXTRA_CONF_FILES
-
 
 Q_RR_CONF_FILE=$NEUTRON_CONF_DIR/rootwrap.conf
 if [[ "$Q_USE_ROOTWRAP" == "False" ]]; then
@@ -359,15 +267,13 @@
 # Hardcoding for 1 service plugin for now
 source $TOP_DIR/lib/neutron_plugins/services/metering
 
-# VPN service plugin functions
-# -------------------------------------------
-# Hardcoding for 1 service plugin for now
-source $TOP_DIR/lib/neutron_plugins/services/vpn
-
 # Firewall Service Plugin functions
 # ---------------------------------
 source $TOP_DIR/lib/neutron_plugins/services/firewall
 
+# L3 Service functions
+source $TOP_DIR/lib/neutron_plugins/services/l3
+
 # Use security group or not
 if has_neutron_plugin_security_group; then
     Q_USE_SECGROUP=${Q_USE_SECGROUP:-True}
@@ -387,22 +293,9 @@
     local cfg_file
     local opts="--config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE"
     for cfg_file in ${Q_PLUGIN_EXTRA_CONF_FILES[@]}; do
-        opts+=" --config-file /$cfg_file"
-    done
-    echo "$opts"
-}
-
-function _determine_config_vpn {
-    local cfg_file
-    local opts="--config-file $NEUTRON_CONF --config-file=$Q_L3_CONF_FILE --config-file=$Q_VPN_CONF_FILE"
-    if is_service_enabled q-fwaas; then
-        opts+=" --config-file $Q_FWAAS_CONF_FILE"
-    fi
-    for cfg_file in ${Q_VPN_EXTRA_CONF_FILES[@]}; do
         opts+=" --config-file $cfg_file"
     done
     echo "$opts"
-
 }
 
 function _determine_config_l3 {
@@ -419,7 +312,6 @@
     local opts=""
     case "$1" in
         "neutron-server") opts="$(_determine_config_server)" ;;
-        "neutron-vpn-agent") opts="$(_determine_config_vpn)" ;;
         "neutron-l3-agent") opts="$(_determine_config_l3)" ;;
     esac
     if [ -z "$opts" ] ; then
@@ -428,16 +320,9 @@
     echo "$opts"
 }
 
-# Test if any Neutron services are enabled
-# is_neutron_enabled
-function is_neutron_enabled {
-    [[ ,${ENABLED_SERVICES} =~ ,"q-" ]] && return 0
-    return 1
-}
-
-# configure_neutron()
+# configure_mutnauq()
 # Set common config for all neutron server and agents.
-function configure_neutron {
+function configure_mutnauq {
     _configure_neutron_common
     iniset_rpc_backend neutron $NEUTRON_CONF
 
@@ -449,10 +334,6 @@
     if is_service_enabled q-metering; then
         _configure_neutron_metering
     fi
-    if is_service_enabled q-vpn; then
-        deprecated "Configuring q-vpn through devstack is deprecated"
-        _configure_neutron_vpn
-    fi
     if is_service_enabled q-fwaas; then
         deprecated "Configuring q-fwaas through devstack is deprecated"
         _configure_neutron_fwaas
@@ -491,9 +372,9 @@
     iniset $NOVA_CONF neutron auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v3"
     iniset $NOVA_CONF neutron username "$Q_ADMIN_USERNAME"
     iniset $NOVA_CONF neutron password "$SERVICE_PASSWORD"
-    iniset $NOVA_CONF neutron user_domain_name "Default"
+    iniset $NOVA_CONF neutron user_domain_name "$SERVICE_DOMAIN_NAME"
     iniset $NOVA_CONF neutron project_name "$SERVICE_PROJECT_NAME"
-    iniset $NOVA_CONF neutron project_domain_name "Default"
+    iniset $NOVA_CONF neutron project_domain_name "$SERVICE_DOMAIN_NAME"
     iniset $NOVA_CONF neutron auth_strategy "$Q_AUTH_STRATEGY"
     iniset $NOVA_CONF neutron region_name "$REGION_NAME"
     iniset $NOVA_CONF neutron url "${Q_PROTOCOL}://$Q_HOST:$Q_PORT"
@@ -514,21 +395,14 @@
     iniset $NOVA_CONF DEFAULT vif_plugging_timeout "$VIF_PLUGGING_TIMEOUT"
 }
 
-# create_neutron_cache_dir() - Part of the _neutron_setup_keystone() process
-function create_neutron_cache_dir {
-    # Create cache dir
-    sudo install -d -o $STACK_USER $NEUTRON_AUTH_CACHE_DIR
-    rm -f $NEUTRON_AUTH_CACHE_DIR/*
-}
-
-# create_neutron_accounts() - Set up common required neutron accounts
+# create_mutnauq_accounts() - Set up common required neutron accounts
 
 # Tenant               User       Roles
 # ------------------------------------------------------------------
 # service              neutron    admin        # if enabled
 
 # Migrated from keystone_data.sh
-function create_neutron_accounts {
+function create_mutnauq_accounts {
     if [[ "$ENABLED_SERVICES" =~ "q-svc" ]]; then
 
         create_service_user "neutron"
@@ -543,107 +417,15 @@
     fi
 }
 
-function create_neutron_initial_network {
-    local project_id
-    project_id=$(openstack project list | grep " demo " | get_field 1)
-    die_if_not_set $LINENO project_id "Failure retrieving project_id for demo"
-
-    # Allow drivers that need to create an initial network to do so here
-    if type -p neutron_plugin_create_initial_network_profile > /dev/null; then
-        neutron_plugin_create_initial_network_profile $PHYSICAL_NETWORK
-    fi
-
-    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 specify the PROVIDER_NETWORK_TYPE"
-        NET_ID=$(neutron net-create $PHYSICAL_NETWORK --tenant_id $project_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 $project_id"
-
-        if [[ "$IP_VERSION" =~ 4.* ]]; then
-            SUBNET_ID=$(neutron subnet-create --tenant_id $project_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)
-            die_if_not_set $LINENO SUBNET_ID "Failure creating SUBNET_ID for $PROVIDER_SUBNET_NAME $project_id"
-        fi
-
-        if [[ "$IP_VERSION" =~ .*6 ]] && [[ -n "$IPV6_PROVIDER_FIXED_RANGE" ]] && [[ -n "$IPV6_PROVIDER_NETWORK_GATEWAY" ]]; then
-            SUBNET_V6_ID=$(neutron subnet-create --tenant_id $project_id --ip_version 6 --ipv6-address-mode $IPV6_ADDRESS_MODE --gateway $IPV6_PROVIDER_NETWORK_GATEWAY --name $IPV6_PROVIDER_SUBNET_NAME $NET_ID $IPV6_PROVIDER_FIXED_RANGE | grep 'id' | get_field 2)
-            die_if_not_set $LINENO SUBNET_V6_ID "Failure creating SUBNET_V6_ID for $IPV6_PROVIDER_SUBNET_NAME $project_id"
-        fi
-
-        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 $project_id "$PRIVATE_NETWORK_NAME" | grep ' id ' | get_field 2)
-        die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PRIVATE_NETWORK_NAME $project_id"
-
-        if [[ "$IP_VERSION" =~ 4.* ]]; then
-            # Create IPv4 private subnet
-            SUBNET_ID=$(_neutron_create_private_subnet_v4 $project_id)
-        fi
-
-        if [[ "$IP_VERSION" =~ .*6 ]]; then
-            # Create IPv6 private subnet
-            IPV6_SUBNET_ID=$(_neutron_create_private_subnet_v6 $project_id)
-        fi
-    fi
-
-    AUTO_ALLOCATE_EXT=$(neutron ext-list | grep 'auto-allocated-topology' | get_field 1)
-    SUBNETPOOL_EXT=$(neutron ext-list | grep 'subnet_allocation' | get_field 1)
-    if [[ "$Q_L3_ENABLED" == "True" ]]; then
-        # Create a router, and add the private subnet as one of its interfaces
-        if [[ "$Q_L3_ROUTER_PER_TENANT" == "True" ]]; then
-            # create a tenant-owned router.
-            ROUTER_ID=$(neutron router-create --tenant-id $project_id $Q_ROUTER_NAME | grep ' id ' | get_field 2)
-            die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $project_id $Q_ROUTER_NAME"
-        else
-            # Plugin only supports creating a single router, which should be admin owned.
-            ROUTER_ID=$(neutron router-create $Q_ROUTER_NAME | grep ' id ' | get_field 2)
-            die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $Q_ROUTER_NAME"
-        fi
-
-        # if the extension is available, then mark the external
-        # network as default, and provision default subnetpools
-        EXTERNAL_NETWORK_FLAGS="--router:external"
-        if [[ -n $AUTO_ALLOCATE_EXT && -n $SUBNETPOOL_EXT ]]; then
-            EXTERNAL_NETWORK_FLAGS="$EXTERNAL_NETWORK_FLAGS --is-default"
-            if [[ "$IP_VERSION" =~ 4.* ]]; then
-                SUBNETPOOL_V4_ID=$(neutron subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V4 --pool-prefix $SUBNETPOOL_PREFIX_V4 --shared --is-default=True | grep ' id ' | get_field 2)
-            fi
-            if [[ "$IP_VERSION" =~ .*6 ]]; then
-                SUBNETPOOL_V6_ID=$(neutron subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V6 --pool-prefix $SUBNETPOOL_PREFIX_V6 --shared --is-default=True | grep ' id ' | get_field 2)
-            fi
-        fi
-        # Create an external network, and a subnet. Configure the external network as router gw
-        if [ "$Q_USE_PROVIDERNET_FOR_PUBLIC" = "True" ]; then
-            EXT_NET_ID=$(neutron net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS --provider:network_type=flat --provider:physical_network=${PUBLIC_PHYSICAL_NETWORK} | grep ' id ' | get_field 2)
-        else
-            EXT_NET_ID=$(neutron net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS | grep ' id ' | get_field 2)
-        fi
-        die_if_not_set $LINENO EXT_NET_ID "Failure creating EXT_NET_ID for $PUBLIC_NETWORK_NAME"
-
-        if [[ "$IP_VERSION" =~ 4.* ]]; then
-            # Configure router for IPv4 public access
-            _neutron_configure_router_v4
-        fi
-
-        if [[ "$IP_VERSION" =~ .*6 ]]; then
-            # Configure router for IPv6 public access
-            _neutron_configure_router_v6
-        fi
-    fi
-}
-
-# init_neutron() - Initialize databases, etc.
-function init_neutron {
+# init_mutnauq() - Initialize databases, etc.
+function init_mutnauq {
     recreate_database $Q_DB_NAME
     # Run Neutron db migrations
     $NEUTRON_BIN_DIR/neutron-db-manage --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE upgrade head
 }
 
-# install_neutron() - Collect source and prepare
-function install_neutron {
+# install_mutnauq() - Collect source and prepare
+function install_mutnauq {
     # Install neutron-lib from git so we make sure we're testing
     # the latest code.
     if use_library_from_git "neutron-lib"; then
@@ -661,10 +443,6 @@
         git_clone $NEUTRON_LBAAS_REPO $NEUTRON_LBAAS_DIR $NEUTRON_LBAAS_BRANCH
         setup_develop $NEUTRON_LBAAS_DIR
     fi
-    if is_service_enabled q-vpn; then
-        git_clone $NEUTRON_VPNAAS_REPO $NEUTRON_VPNAAS_DIR $NEUTRON_VPNAAS_BRANCH
-        setup_develop $NEUTRON_VPNAAS_DIR
-    fi
 
     if [ "$VIRT_DRIVER" == 'xenserver' ]; then
         local dom0_ip
@@ -685,15 +463,6 @@
     fi
 }
 
-# install_neutronclient() - Collect source and prepare
-function install_neutronclient {
-    if use_library_from_git "python-neutronclient"; then
-        git_clone_by_name "python-neutronclient"
-        setup_dev_lib "python-neutronclient"
-        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-neutronclient"]}/tools/,/etc/bash_completion.d/}neutron.bash_completion
-    fi
-}
-
 # install_neutron_agent_packages() - Collect source and prepare
 function install_neutron_agent_packages {
     # radvd doesn't come with the OS. Install it if the l3 service is enabled.
@@ -740,7 +509,7 @@
 
 # Control of the l2 agent is separated out to make it easier to test partial
 # upgrades (everything upgraded except the L2 agent)
-function start_neutron_l2_agent {
+function start_mutnauq_l2_agent {
     run_process q-agt "$AGENT_BINARY --config-file $NEUTRON_CONF --config-file /$Q_PLUGIN_CONF_FILE"
 
     if is_provider_network && [[ $Q_AGENT == "openvswitch" ]]; then
@@ -758,13 +527,11 @@
     fi
 }
 
-function start_neutron_other_agents {
+function start_mutnauq_other_agents {
     run_process q-dhcp "$AGENT_DHCP_BINARY --config-file $NEUTRON_CONF --config-file=$Q_DHCP_CONF_FILE"
 
     if is_service_enabled neutron-vpnaas; then
         :  # Started by plugin
-    elif is_service_enabled q-vpn; then
-        run_process q-vpn "$AGENT_VPN_BINARY $(determine_config_files neutron-vpn-agent)"
     else
         run_process q-l3 "$AGENT_L3_BINARY $(determine_config_files neutron-l3-agent)"
     fi
@@ -782,15 +549,16 @@
 # Start running processes, including screen
 function start_neutron_agents {
     # Start up the neutron agents if enabled
-    start_neutron_l2_agent
-    start_neutron_other_agents
+    start_mutnauq_l2_agent
+    start_mutnauq_other_agents
 }
 
-function stop_neutron_l2_agent {
+function stop_mutnauq_l2_agent {
     stop_process q-agt
 }
 
-function stop_neutron_other {
+# stop_mutnauq_other() - Stop running processes (non-screen)
+function stop_mutnauq_other {
     if is_service_enabled q-dhcp; then
         stop_process q-dhcp
         pid=$(ps aux | awk '/[d]nsmasq.+interface=(tap|ns-)/ { print $2 }')
@@ -815,9 +583,6 @@
     if is_service_enabled q-fwaas; then
         neutron_fwaas_stop
     fi
-    if is_service_enabled q-vpn; then
-        neutron_vpn_stop
-    fi
     if is_service_enabled q-metering; then
         neutron_metering_stop
     fi
@@ -828,9 +593,9 @@
 }
 
 # stop_neutron() - Stop running processes (non-screen)
-function stop_neutron {
-    stop_neutron_other
-    stop_neutron_l2_agent
+function stop_mutnauq {
+    stop_mutnauq_other
+    stop_mutnauq_l2_agent
 }
 
 # _move_neutron_addresses_route() - Move the primary IP to the OVS bridge
@@ -859,6 +624,13 @@
 
         IP_BRD=$(ip -f $af a s dev $from_intf scope global primary | grep inet | awk '{ print $2, $3, $4; exit }')
 
+        if [[ "$af" == "inet" ]]; then
+            IP=$(echo $IP_BRD | awk '{ print $1; exit }' | grep -o -E '(.*)/' | cut -d "/" -f1)
+            ARP_CMD="arping -A -c 3 -w 4.5 -I $to_intf $IP "
+        else
+            ARP_CMD=""
+        fi
+
         if [ "$DEFAULT_ROUTE_GW" != "" ]; then
             ADD_DEFAULT_ROUTE="sudo ip -f $af r replace default via $DEFAULT_ROUTE_GW dev $to_intf"
         fi
@@ -879,13 +651,13 @@
 
         # The add/del OVS port calls have to happen either before or
         # after the address is moved in order to not leave it orphaned.
-        $DEL_OVS_PORT; $IP_DEL; $IP_ADD; $IP_UP; $ADD_OVS_PORT; $ADD_DEFAULT_ROUTE
+        $DEL_OVS_PORT; $IP_DEL; $IP_ADD; $IP_UP; $ADD_OVS_PORT; $ADD_DEFAULT_ROUTE; $ARP_CMD
     fi
 }
 
-# cleanup_neutron() - Remove residual data files, anything left over from previous
+# cleanup_mutnauq() - Remove residual data files, anything left over from previous
 # runs that a clean run would need to clean up
-function cleanup_neutron {
+function cleanup_mutnauq {
 
     if [[ -n "$OVS_PHYSICAL_BRIDGE" ]]; then
         _move_neutron_addresses_route "$OVS_PHYSICAL_BRIDGE" "$PUBLIC_INTERFACE" False True "inet"
@@ -946,10 +718,11 @@
 
     # Set plugin-specific variables ``Q_DB_NAME``, ``Q_PLUGIN_CLASS``.
     # For main plugin config file, set ``Q_PLUGIN_CONF_PATH``, ``Q_PLUGIN_CONF_FILENAME``.
-    # For addition plugin config files, set ``Q_PLUGIN_EXTRA_CONF_PATH``,
+    # For additional plugin config files, set ``Q_PLUGIN_EXTRA_CONF_PATH`` and
     # ``Q_PLUGIN_EXTRA_CONF_FILES``.  For example:
     #
-    #    ``Q_PLUGIN_EXTRA_CONF_FILES=(file1, file2)``
+    #    ``Q_PLUGIN_EXTRA_CONF_PATH=/path/to/plugins``
+    #    ``Q_PLUGIN_EXTRA_CONF_FILES=(file1 file2)``
     neutron_plugin_configure_common
 
     if [[ "$Q_PLUGIN_CONF_PATH" == '' || "$Q_PLUGIN_CONF_FILENAME" == '' || "$Q_PLUGIN_CLASS" == '' ]]; then
@@ -973,6 +746,9 @@
     iniset $NEUTRON_CONF DEFAULT bind_host $Q_LISTEN_ADDRESS
     iniset $NEUTRON_CONF oslo_concurrency lock_path $DATA_DIR/neutron/lock
 
+    # NOTE(freerunner): Need to adjust Region Name for nova in multiregion installation
+    iniset $NEUTRON_CONF nova region_name $REGION_NAME
+
     # 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"
@@ -1068,31 +844,6 @@
     neutron_plugin_configure_dhcp_agent
 }
 
-function _configure_neutron_l3_agent {
-    Q_L3_ENABLED=True
-
-    if is_service_enabled q-vpn; then
-        neutron_vpn_configure_agent
-    fi
-
-    cp $NEUTRON_DIR/etc/l3_agent.ini.sample $Q_L3_CONF_FILE
-
-    iniset $Q_L3_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
-    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"
-    fi
-
-    _neutron_setup_interface_driver $Q_L3_CONF_FILE
-
-    neutron_plugin_configure_l3_agent
-
-    _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" True False "inet"
-
-    if [[ $(ip -f inet6 a s dev "$PUBLIC_INTERFACE" | grep -c 'global') != 0 ]]; then
-        _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" False False "inet6"
-    fi
-}
 
 function _configure_neutron_metadata_agent {
     cp $NEUTRON_DIR/etc/metadata_agent.ini.sample $Q_META_CONF_FILE
@@ -1134,17 +885,6 @@
     neutron_fwaas_configure_driver
 }
 
-function _configure_neutron_vpn {
-    # 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
-}
-
 function _configure_dvr {
     iniset $NEUTRON_CONF DEFAULT router_distributed True
     iniset $Q_L3_CONF_FILE DEFAULT agent_mode $Q_DVR_MODE
@@ -1190,14 +930,7 @@
     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
 
-    iniset $NEUTRON_CONF nova auth_type password
-    iniset $NEUTRON_CONF nova auth_url $KEYSTONE_AUTH_URI
-    iniset $NEUTRON_CONF nova username nova
-    iniset $NEUTRON_CONF nova password $SERVICE_PASSWORD
-    iniset $NEUTRON_CONF nova user_domain_id default
-    iniset $NEUTRON_CONF nova project_name $SERVICE_PROJECT_NAME
-    iniset $NEUTRON_CONF nova project_domain_id default
-    iniset $NEUTRON_CONF nova region_name $REGION_NAME
+    configure_auth_token_middleware $NEUTRON_CONF nova $NEUTRON_AUTH_CACHE_DIR nova
 
     # Configure plugin
     neutron_plugin_configure_service
@@ -1285,164 +1018,6 @@
 
     neutron_plugin_setup_interface_driver $1
 }
-
-# Create private IPv4 subnet
-function _neutron_create_private_subnet_v4 {
-    local project_id=$1
-    local subnet_params="--tenant-id $project_id "
-    subnet_params+="--ip_version 4 "
-    subnet_params+="--gateway $NETWORK_GATEWAY "
-    subnet_params+="--name $PRIVATE_SUBNET_NAME "
-    subnet_params+="$NET_ID $FIXED_RANGE"
-    local subnet_id
-    subnet_id=$(neutron subnet-create $subnet_params | grep ' id ' | get_field 2)
-    die_if_not_set $LINENO subnet_id "Failure creating private IPv4 subnet for $project_id"
-    echo $subnet_id
-}
-
-# Create private IPv6 subnet
-function _neutron_create_private_subnet_v6 {
-    local project_id=$1
-    die_if_not_set $LINENO IPV6_RA_MODE "IPV6 RA Mode not set"
-    die_if_not_set $LINENO IPV6_ADDRESS_MODE "IPV6 Address Mode not set"
-    local ipv6_modes="--ipv6-ra-mode $IPV6_RA_MODE --ipv6-address-mode $IPV6_ADDRESS_MODE"
-    local subnet_params="--tenant-id $project_id "
-    subnet_params+="--ip_version 6 "
-    subnet_params+="--gateway $IPV6_PRIVATE_NETWORK_GATEWAY "
-    subnet_params+="--name $IPV6_PRIVATE_SUBNET_NAME "
-    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)
-    die_if_not_set $LINENO ipv6_subnet_id "Failure creating private IPv6 subnet for $project_id"
-    echo $ipv6_subnet_id
-}
-
-# Create public IPv4 subnet
-function _neutron_create_public_subnet_v4 {
-    local subnet_params+="--ip_version 4 "
-    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+="$EXT_NET_ID $FLOATING_RANGE "
-    subnet_params+="-- --enable_dhcp=False"
-    local id_and_ext_gw_ip
-    id_and_ext_gw_ip=$(neutron subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ')
-    die_if_not_set $LINENO id_and_ext_gw_ip "Failure creating public IPv4 subnet"
-    echo $id_and_ext_gw_ip
-}
-
-# Create public IPv6 subnet
-function _neutron_create_public_subnet_v6 {
-    local subnet_params="--ip_version 6 "
-    subnet_params+="--gateway $IPV6_PUBLIC_NETWORK_GATEWAY "
-    subnet_params+="--name $IPV6_PUBLIC_SUBNET_NAME "
-    subnet_params+="$EXT_NET_ID $IPV6_PUBLIC_RANGE "
-    subnet_params+="-- --enable_dhcp=False"
-    local ipv6_id_and_ext_gw_ip
-    ipv6_id_and_ext_gw_ip=$(neutron subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ')
-    die_if_not_set $LINENO ipv6_id_and_ext_gw_ip "Failure creating an IPv6 public subnet"
-    echo $ipv6_id_and_ext_gw_ip
-}
-
-# Configure neutron router for IPv4 public access
-function _neutron_configure_router_v4 {
-    neutron router-interface-add $ROUTER_ID $SUBNET_ID
-    # Create a public subnet on the external network
-    local id_and_ext_gw_ip
-    id_and_ext_gw_ip=$(_neutron_create_public_subnet_v4 $EXT_NET_ID)
-    local ext_gw_ip
-    ext_gw_ip=$(echo $id_and_ext_gw_ip  | get_field 2)
-    PUB_SUBNET_ID=$(echo $id_and_ext_gw_ip | get_field 5)
-    # Configure the external network as the default router gateway
-    neutron router-gateway-set $ROUTER_ID $EXT_NET_ID
-
-    # This logic is specific to using the l3-agent for layer 3
-    if is_service_enabled q-l3; then
-        # Configure and enable public bridge
-        local ext_gw_interface="none"
-        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
-            # will be using.
-            # e.x. brq3592e767-da for NET_ID 3592e767-da66-4bcb-9bec-cdb03cd96102
-            ext_gw_interface=brq${EXT_NET_ID:0:11}
-        fi
-        if [[ "$ext_gw_interface" != "none" ]]; then
-            local cidr_len=${FLOATING_RANGE#*/}
-            local testcmd="ip -o link | grep -q $ext_gw_interface"
-            test_with_retry "$testcmd" "$ext_gw_interface creation failed"
-            if [[ $(ip addr show dev $ext_gw_interface | grep -c $ext_gw_ip) == 0 && ( $Q_USE_PROVIDERNET_FOR_PUBLIC == "False" || $Q_USE_PUBLIC_VETH == "True" ) ]]; then
-                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'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
-        _neutron_set_router_id
-    fi
-}
-
-# Configure neutron router for IPv6 public access
-function _neutron_configure_router_v6 {
-    neutron router-interface-add $ROUTER_ID $IPV6_SUBNET_ID
-    # Create a public subnet on the external network
-    local ipv6_id_and_ext_gw_ip
-    ipv6_id_and_ext_gw_ip=$(_neutron_create_public_subnet_v6 $EXT_NET_ID)
-    local ipv6_ext_gw_ip
-    ipv6_ext_gw_ip=$(echo $ipv6_id_and_ext_gw_ip | get_field 2)
-    local ipv6_pub_subnet_id
-    ipv6_pub_subnet_id=$(echo $ipv6_id_and_ext_gw_ip | get_field 5)
-
-    # If the external network has not already been set as the default router
-    # gateway when configuring an IPv4 public subnet, do so now
-    if [[ "$IP_VERSION" == "6" ]]; then
-        neutron router-gateway-set $ROUTER_ID $EXT_NET_ID
-    fi
-
-    # This logic is specific to using the l3-agent for layer 3
-    if is_service_enabled q-l3; then
-        # Ensure IPv6 forwarding is enabled on the host
-        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'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; then
-            local ext_gw_interface
-            ext_gw_interface=$(_neutron_get_ext_gw_interface)
-            local ipv6_cidr_len=${IPV6_PUBLIC_RANGE#*/}
-
-            # Configure interface for public bridge
-            sudo ip -6 addr add $ipv6_ext_gw_ip/$ipv6_cidr_len dev $ext_gw_interface
-            sudo ip -6 route replace $FIXED_RANGE_V6 via $IPV6_ROUTER_GW_IP dev $ext_gw_interface
-        fi
-        _neutron_set_router_id
-    fi
-}
-
-# Explicitly set router id in l3 agent configuration
-function _neutron_set_router_id {
-    if [[ "$Q_L3_ROUTER_PER_TENANT" == "False" ]]; then
-        iniset $Q_L3_CONF_FILE DEFAULT router_id $ROUTER_ID
-    fi
-}
-
-# Get ext_gw_interface depending on value of Q_USE_PUBLIC_VETH
-function _neutron_get_ext_gw_interface {
-    if [[ "$Q_USE_PUBLIC_VETH" == "True" ]]; then
-        echo $Q_PUBLIC_VETH_EX
-    else
-        # Disable in-band as we are going to use local port
-        # to communicate with VMs
-        sudo ovs-vsctl set Bridge $PUBLIC_BRIDGE \
-            other_config:disable-in-band=true
-        echo $PUBLIC_BRIDGE
-    fi
-}
-
 # Functions for Neutron Exercises
 #--------------------------------
 
@@ -1472,7 +1047,7 @@
 }
 
 function _get_net_id {
-    neutron --os-tenant-name admin --os-username admin --os-password $ADMIN_PASSWORD net-list | grep $1 | awk '{print $2}'
+    neutron --os-cloud devstack-admin --os-region "$REGION_NAME" --os-tenant-name admin --os-username admin --os-password $ADMIN_PASSWORD net-list | grep $1 | awk '{print $2}'
 }
 
 function _get_probe_cmd_prefix {
@@ -1544,14 +1119,6 @@
     _neutron_third_party_do check
 }
 
-function is_provider_network {
-    if [ "$Q_USE_PROVIDER_NETWORKING" == "True" ] && [ "$Q_L3_ENABLED" == "False" ]; then
-        return 0
-    fi
-    return 1
-}
-
-
 # Restore xtrace
 $_XTRACE_NEUTRON
 
diff --git a/lib/neutron_plugins/linuxbridge_agent b/lib/neutron_plugins/linuxbridge_agent
index 096722b..0a06635 100644
--- a/lib/neutron_plugins/linuxbridge_agent
+++ b/lib/neutron_plugins/linuxbridge_agent
@@ -43,13 +43,15 @@
 }
 
 function neutron_plugin_configure_dhcp_agent {
-    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport
+    local conf_file=$1
+    iniset $conf_file DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport
 }
 
 function neutron_plugin_configure_l3_agent {
+    local conf_file=$1
     sudo brctl addbr $PUBLIC_BRIDGE
-    iniset $Q_L3_CONF_FILE DEFAULT external_network_bridge
-    iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport
+    iniset $conf_file DEFAULT external_network_bridge
+    iniset $conf_file DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport
 }
 
 function neutron_plugin_configure_plugin_agent {
diff --git a/lib/neutron_plugins/openvswitch_agent b/lib/neutron_plugins/openvswitch_agent
index 339d5fd..69e38f4 100644
--- a/lib/neutron_plugins/openvswitch_agent
+++ b/lib/neutron_plugins/openvswitch_agent
@@ -28,12 +28,14 @@
 }
 
 function neutron_plugin_configure_dhcp_agent {
-    iniset $Q_DHCP_CONF_FILE DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport
+    local conf_file=$1
+    iniset $conf_file DEFAULT dhcp_agent_manager neutron.agent.dhcp_agent.DhcpAgentWithStateReport
 }
 
 function neutron_plugin_configure_l3_agent {
+    local conf_file=$1
     _neutron_ovs_base_configure_l3_agent
-    iniset $Q_L3_CONF_FILE DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport
+    iniset $conf_file DEFAULT l3_agent_manager neutron.agent.l3_agent.L3NATAgentWithStateReport
 }
 
 function neutron_plugin_configure_plugin_agent {
@@ -96,17 +98,17 @@
 
         # Set up domU's L2 agent:
 
-        # 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 -- --may-exist add-port "br-$GUEST_INTERFACE_DEFAULT" $GUEST_INTERFACE_DEFAULT
+        # Create a bridge "br-$VLAN_INTERFACE"
+        _neutron_ovs_base_add_bridge "br-$VLAN_INTERFACE"
+        # Add $VLAN_INTERFACE to that bridge
+        sudo ovs-vsctl -- --may-exist add-port "br-$VLAN_INTERFACE" $VLAN_INTERFACE
 
         # 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
+        sudo ovs-vsctl -- --may-exist add-port $PUBLIC_BRIDGE $PUBLIC_INTERFACE
 
         # Set bridge mappings to "physnet1:br-$GUEST_INTERFACE_DEFAULT"
-        iniset "/$Q_PLUGIN_CONF_FILE.domU" ovs bridge_mappings "physnet1:br-$GUEST_INTERFACE_DEFAULT,physnet-ex:$PUBLIC_BRIDGE"
+        iniset "/$Q_PLUGIN_CONF_FILE.domU" ovs bridge_mappings "physnet1:br-$VLAN_INTERFACE,physnet-ex:$PUBLIC_BRIDGE"
         # Set integration bridge to domU's
         iniset "/$Q_PLUGIN_CONF_FILE.domU" ovs integration_bridge $OVS_BRIDGE
         # Set root wrap
diff --git a/lib/neutron_plugins/services/l3 b/lib/neutron_plugins/services/l3
new file mode 100644
index 0000000..a5a6c81
--- /dev/null
+++ b/lib/neutron_plugins/services/l3
@@ -0,0 +1,366 @@
+#!/bin/bash
+# Subnet IP version
+IP_VERSION=${IP_VERSION:-"4+6"}
+# Validate IP_VERSION
+if [[ $IP_VERSION != "4" ]] && [[ $IP_VERSION != "6" ]] && [[ $IP_VERSION != "4+6" ]]; then
+    die $LINENO "IP_VERSION must be either 4, 6, or 4+6"
+fi
+# Specify if the initial private and external networks should be created
+NEUTRON_CREATE_INITIAL_NETWORKS=${NEUTRON_CREATE_INITIAL_NETWORKS:-True}
+
+## Provider Network Information
+PROVIDER_SUBNET_NAME=${PROVIDER_SUBNET_NAME:-"provider_net"}
+IPV6_PROVIDER_SUBNET_NAME=${IPV6_PROVIDER_SUBNET_NAME:-"provider_net_v6"}
+IPV6_PROVIDER_FIXED_RANGE=${IPV6_PROVIDER_FIXED_RANGE:-}
+IPV6_PROVIDER_NETWORK_GATEWAY=${IPV6_PROVIDER_NETWORK_GATEWAY:-}
+
+PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex}
+
+# If Q_USE_PUBLIC_VETH=True, create and use a veth pair instead of
+# PUBLIC_BRIDGE.  This is intended to be used with
+# Q_USE_PROVIDERNET_FOR_PUBLIC=True.
+Q_USE_PUBLIC_VETH=${Q_USE_PUBLIC_VETH:-False}
+Q_PUBLIC_VETH_EX=${Q_PUBLIC_VETH_EX:-veth-pub-ex}
+Q_PUBLIC_VETH_INT=${Q_PUBLIC_VETH_INT:-veth-pub-int}
+
+# The next variable is configured by plugin
+# e.g.  _configure_neutron_l3_agent or lib/neutron_plugins/*
+#
+# L3 routers exist per tenant
+Q_L3_ROUTER_PER_TENANT=${Q_L3_ROUTER_PER_TENANT:-True}
+
+
+# Use flat providernet for public network
+#
+# If Q_USE_PROVIDERNET_FOR_PUBLIC=True, use a flat provider network
+# for external interface of neutron l3-agent.  In that case,
+# PUBLIC_PHYSICAL_NETWORK specifies provider:physical_network value
+# used for the network.  In case of ofagent, you should add the
+# corresponding entry to your OFAGENT_PHYSICAL_INTERFACE_MAPPINGS.
+# For openvswitch agent, you should add the corresponding entry to
+# your OVS_BRIDGE_MAPPINGS.
+#
+# eg.  (ofagent)
+#    Q_USE_PROVIDERNET_FOR_PUBLIC=True
+#    Q_USE_PUBLIC_VETH=True
+#    PUBLIC_PHYSICAL_NETWORK=public
+#    OFAGENT_PHYSICAL_INTERFACE_MAPPINGS=public:veth-pub-int
+#
+# eg.  (openvswitch agent)
+#    Q_USE_PROVIDERNET_FOR_PUBLIC=True
+#    PUBLIC_PHYSICAL_NETWORK=public
+#    OVS_BRIDGE_MAPPINGS=public:br-ex
+Q_USE_PROVIDERNET_FOR_PUBLIC=${Q_USE_PROVIDERNET_FOR_PUBLIC:-False}
+PUBLIC_PHYSICAL_NETWORK=${PUBLIC_PHYSICAL_NETWORK:-public}
+
+# Generate 40-bit IPv6 Global ID to comply with RFC 4193
+IPV6_GLOBAL_ID=`uuidgen | sed s/-//g | cut -c 23- | sed -e "s/\(..\)\(....\)\(....\)/\1:\2:\3/"`
+
+# IPv6 gateway and subnet defaults, in case they are not customized in localrc
+IPV6_RA_MODE=${IPV6_RA_MODE:-slaac}
+IPV6_ADDRESS_MODE=${IPV6_ADDRESS_MODE:-slaac}
+IPV6_PUBLIC_SUBNET_NAME=${IPV6_PUBLIC_SUBNET_NAME:-ipv6-public-subnet}
+IPV6_PRIVATE_SUBNET_NAME=${IPV6_PRIVATE_SUBNET_NAME:-ipv6-private-subnet}
+FIXED_RANGE_V6=${FIXED_RANGE_V6:-fd$IPV6_GLOBAL_ID::/64}
+IPV6_PRIVATE_NETWORK_GATEWAY=${IPV6_PRIVATE_NETWORK_GATEWAY:-fd$IPV6_GLOBAL_ID::1}
+IPV6_PUBLIC_RANGE=${IPV6_PUBLIC_RANGE:-2001:db8::/64}
+IPV6_PUBLIC_NETWORK_GATEWAY=${IPV6_PUBLIC_NETWORK_GATEWAY:-2001:db8::2}
+IPV6_ROUTER_GW_IP=${IPV6_ROUTER_GW_IP:-2001:db8::1}
+
+# Gateway and subnet defaults, in case they are not customized in localrc
+NETWORK_GATEWAY=${NETWORK_GATEWAY:-10.0.0.1}
+PUBLIC_NETWORK_GATEWAY=${PUBLIC_NETWORK_GATEWAY:-172.24.4.1}
+PRIVATE_SUBNET_NAME=${PRIVATE_SUBNET_NAME:-"private-subnet"}
+PUBLIC_SUBNET_NAME=${PUBLIC_SUBNET_NAME:-"public-subnet"}
+
+# Subnetpool defaults
+SUBNETPOOL_NAME=${SUBNETPOOL_NAME:-"shared-default-subnetpool"}
+
+SUBNETPOOL_PREFIX_V4=${SUBNETPOOL_PREFIX_V4:-10.0.0.0/8}
+SUBNETPOOL_PREFIX_V6=${SUBNETPOOL_PREFIX_V6:-2001:db8:8000::/48}
+
+SUBNETPOOL_SIZE_V4=${SUBNETPOOL_SIZE_V4:-24}
+SUBNETPOOL_SIZE_V6=${SUBNETPOOL_SIZE_V6:-64}
+
+function _determine_config_l3 {
+    local opts="--config-file $NEUTRON_CONF --config-file=$Q_L3_CONF_FILE"
+    echo "$opts"
+}
+
+function _configure_neutron_l3_agent {
+
+    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 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"
+    fi
+
+    _neutron_setup_interface_driver $Q_L3_CONF_FILE
+
+    neutron_plugin_configure_l3_agent
+
+    _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" True False "inet"
+
+    if [[ $(ip -f inet6 a s dev "$PUBLIC_INTERFACE" | grep -c 'global') != 0 ]]; then
+        _move_neutron_addresses_route "$PUBLIC_INTERFACE" "$OVS_PHYSICAL_BRIDGE" False False "inet6"
+    fi
+}
+
+# Explicitly set router id in l3 agent configuration
+function _neutron_set_router_id {
+    if [[ "$Q_L3_ROUTER_PER_TENANT" == "False" ]]; then
+        iniset $Q_L3_CONF_FILE DEFAULT router_id $ROUTER_ID
+    fi
+}
+
+# Get ext_gw_interface depending on value of Q_USE_PUBLIC_VETH
+function _neutron_get_ext_gw_interface {
+    if [[ "$Q_USE_PUBLIC_VETH" == "True" ]]; then
+        echo $Q_PUBLIC_VETH_EX
+    else
+        # Disable in-band as we are going to use local port
+        # to communicate with VMs
+        sudo ovs-vsctl set Bridge $PUBLIC_BRIDGE \
+            other_config:disable-in-band=true
+        echo $PUBLIC_BRIDGE
+    fi
+}
+
+function create_neutron_initial_network {
+    local project_id
+    project_id=$(openstack project list | grep " demo " | get_field 1)
+    die_if_not_set $LINENO project_id "Failure retrieving project_id for demo"
+
+    # Allow drivers that need to create an initial network to do so here
+    if type -p neutron_plugin_create_initial_network_profile > /dev/null; then
+        neutron_plugin_create_initial_network_profile $PHYSICAL_NETWORK
+    fi
+
+    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 specify the PROVIDER_NETWORK_TYPE"
+        NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create $PHYSICAL_NETWORK --tenant_id $project_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 $project_id"
+
+        if [[ "$IP_VERSION" =~ 4.* ]]; then
+            SUBNET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create --tenant_id $project_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)
+            die_if_not_set $LINENO SUBNET_ID "Failure creating SUBNET_ID for $PROVIDER_SUBNET_NAME $project_id"
+        fi
+
+        if [[ "$IP_VERSION" =~ .*6 ]] && [[ -n "$IPV6_PROVIDER_FIXED_RANGE" ]] && [[ -n "$IPV6_PROVIDER_NETWORK_GATEWAY" ]]; then
+            SUBNET_V6_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create --tenant_id $project_id --ip_version 6 --ipv6-address-mode $IPV6_ADDRESS_MODE --gateway $IPV6_PROVIDER_NETWORK_GATEWAY --name $IPV6_PROVIDER_SUBNET_NAME $NET_ID $IPV6_PROVIDER_FIXED_RANGE | grep 'id' | get_field 2)
+            die_if_not_set $LINENO SUBNET_V6_ID "Failure creating SUBNET_V6_ID for $IPV6_PROVIDER_SUBNET_NAME $project_id"
+        fi
+
+        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 --os-cloud devstack-admin --os-region "$REGION_NAME" net-create --tenant-id $project_id "$PRIVATE_NETWORK_NAME" | grep ' id ' | get_field 2)
+        die_if_not_set $LINENO NET_ID "Failure creating NET_ID for $PRIVATE_NETWORK_NAME $project_id"
+
+        if [[ "$IP_VERSION" =~ 4.* ]]; then
+            # Create IPv4 private subnet
+            SUBNET_ID=$(_neutron_create_private_subnet_v4 $project_id)
+        fi
+
+        if [[ "$IP_VERSION" =~ .*6 ]]; then
+            # Create IPv6 private subnet
+            IPV6_SUBNET_ID=$(_neutron_create_private_subnet_v6 $project_id)
+        fi
+    fi
+
+    AUTO_ALLOCATE_EXT=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" ext-list | grep 'auto-allocated-topology' | get_field 1)
+    SUBNETPOOL_EXT=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" ext-list | grep 'subnet_allocation' | get_field 1)
+    if is_service_enabled q-l3; then
+        # Create a router, and add the private subnet as one of its interfaces
+        if [[ "$Q_L3_ROUTER_PER_TENANT" == "True" ]]; then
+            # create a tenant-owned router.
+            ROUTER_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-create --tenant-id $project_id $Q_ROUTER_NAME | grep ' id ' | get_field 2)
+            die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $project_id $Q_ROUTER_NAME"
+        else
+            # Plugin only supports creating a single router, which should be admin owned.
+            ROUTER_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-create $Q_ROUTER_NAME | grep ' id ' | get_field 2)
+            die_if_not_set $LINENO ROUTER_ID "Failure creating ROUTER_ID for $Q_ROUTER_NAME"
+        fi
+
+        # if the extension is available, then mark the external
+        # network as default, and provision default subnetpools
+        EXTERNAL_NETWORK_FLAGS="--router:external"
+        if [[ -n $AUTO_ALLOCATE_EXT && -n $SUBNETPOOL_EXT ]]; then
+            EXTERNAL_NETWORK_FLAGS="$EXTERNAL_NETWORK_FLAGS --is-default"
+            if [[ "$IP_VERSION" =~ 4.* ]]; then
+                SUBNETPOOL_V4_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V4 --pool-prefix $SUBNETPOOL_PREFIX_V4 --shared --is-default=True | grep ' id ' | get_field 2)
+            fi
+            if [[ "$IP_VERSION" =~ .*6 ]]; then
+                SUBNETPOOL_V6_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnetpool-create $SUBNETPOOL_NAME --default-prefixlen $SUBNETPOOL_SIZE_V6 --pool-prefix $SUBNETPOOL_PREFIX_V6 --shared --is-default=True | grep ' id ' | get_field 2)
+            fi
+        fi
+        # Create an external network, and a subnet. Configure the external network as router gw
+        if [ "$Q_USE_PROVIDERNET_FOR_PUBLIC" = "True" ]; then
+            EXT_NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS --provider:network_type=flat --provider:physical_network=${PUBLIC_PHYSICAL_NETWORK} | grep ' id ' | get_field 2)
+        else
+            EXT_NET_ID=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" net-create "$PUBLIC_NETWORK_NAME" -- $EXTERNAL_NETWORK_FLAGS | grep ' id ' | get_field 2)
+        fi
+        die_if_not_set $LINENO EXT_NET_ID "Failure creating EXT_NET_ID for $PUBLIC_NETWORK_NAME"
+
+        if [[ "$IP_VERSION" =~ 4.* ]]; then
+            # Configure router for IPv4 public access
+            _neutron_configure_router_v4
+        fi
+
+        if [[ "$IP_VERSION" =~ .*6 ]]; then
+            # Configure router for IPv6 public access
+            _neutron_configure_router_v6
+        fi
+    fi
+}
+
+# Create private IPv4 subnet
+function _neutron_create_private_subnet_v4 {
+    local project_id=$1
+    local subnet_params="--tenant-id $project_id "
+    subnet_params+="--ip_version 4 "
+    subnet_params+="--gateway $NETWORK_GATEWAY "
+    subnet_params+="--name $PRIVATE_SUBNET_NAME "
+    subnet_params+="$NET_ID $FIXED_RANGE"
+    local subnet_id
+    subnet_id=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep ' id ' | get_field 2)
+    die_if_not_set $LINENO subnet_id "Failure creating private IPv4 subnet for $project_id"
+    echo $subnet_id
+}
+
+# Create private IPv6 subnet
+function _neutron_create_private_subnet_v6 {
+    local project_id=$1
+    die_if_not_set $LINENO IPV6_RA_MODE "IPV6 RA Mode not set"
+    die_if_not_set $LINENO IPV6_ADDRESS_MODE "IPV6 Address Mode not set"
+    local ipv6_modes="--ipv6-ra-mode $IPV6_RA_MODE --ipv6-address-mode $IPV6_ADDRESS_MODE"
+    local subnet_params="--tenant-id $project_id "
+    subnet_params+="--ip_version 6 "
+    subnet_params+="--gateway $IPV6_PRIVATE_NETWORK_GATEWAY "
+    subnet_params+="--name $IPV6_PRIVATE_SUBNET_NAME "
+    subnet_params+="$NET_ID $FIXED_RANGE_V6 $ipv6_modes"
+    local ipv6_subnet_id
+    ipv6_subnet_id=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep ' id ' | get_field 2)
+    die_if_not_set $LINENO ipv6_subnet_id "Failure creating private IPv6 subnet for $project_id"
+    echo $ipv6_subnet_id
+}
+
+# Create public IPv4 subnet
+function _neutron_create_public_subnet_v4 {
+    local subnet_params+="--ip_version 4 "
+    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+="$EXT_NET_ID $FLOATING_RANGE "
+    subnet_params+="-- --enable_dhcp=False"
+    local id_and_ext_gw_ip
+    id_and_ext_gw_ip=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ')
+    die_if_not_set $LINENO id_and_ext_gw_ip "Failure creating public IPv4 subnet"
+    echo $id_and_ext_gw_ip
+}
+
+# Create public IPv6 subnet
+function _neutron_create_public_subnet_v6 {
+    local subnet_params="--ip_version 6 "
+    subnet_params+="--gateway $IPV6_PUBLIC_NETWORK_GATEWAY "
+    subnet_params+="--name $IPV6_PUBLIC_SUBNET_NAME "
+    subnet_params+="$EXT_NET_ID $IPV6_PUBLIC_RANGE "
+    subnet_params+="-- --enable_dhcp=False"
+    local ipv6_id_and_ext_gw_ip
+    ipv6_id_and_ext_gw_ip=$(neutron --os-cloud devstack-admin --os-region "$REGION_NAME" subnet-create $subnet_params | grep -e 'gateway_ip' -e ' id ')
+    die_if_not_set $LINENO ipv6_id_and_ext_gw_ip "Failure creating an IPv6 public subnet"
+    echo $ipv6_id_and_ext_gw_ip
+}
+
+# Configure neutron router for IPv4 public access
+function _neutron_configure_router_v4 {
+    neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-interface-add $ROUTER_ID $SUBNET_ID
+    # Create a public subnet on the external network
+    local id_and_ext_gw_ip
+    id_and_ext_gw_ip=$(_neutron_create_public_subnet_v4 $EXT_NET_ID)
+    local ext_gw_ip
+    ext_gw_ip=$(echo $id_and_ext_gw_ip  | get_field 2)
+    PUB_SUBNET_ID=$(echo $id_and_ext_gw_ip | get_field 5)
+    # Configure the external network as the default router gateway
+    neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-gateway-set $ROUTER_ID $EXT_NET_ID
+
+    # This logic is specific to using the l3-agent for layer 3
+    if is_service_enabled q-l3; then
+        # Configure and enable public bridge
+        local ext_gw_interface="none"
+        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
+            # will be using.
+            # e.x. brq3592e767-da for NET_ID 3592e767-da66-4bcb-9bec-cdb03cd96102
+            ext_gw_interface=brq${EXT_NET_ID:0:11}
+        fi
+        if [[ "$ext_gw_interface" != "none" ]]; then
+            local cidr_len=${FLOATING_RANGE#*/}
+            local testcmd="ip -o link | grep -q $ext_gw_interface"
+            test_with_retry "$testcmd" "$ext_gw_interface creation failed"
+            if [[ $(ip addr show dev $ext_gw_interface | grep -c $ext_gw_ip) == 0 && ( $Q_USE_PROVIDERNET_FOR_PUBLIC == "False" || $Q_USE_PUBLIC_VETH == "True" ) ]]; then
+                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 --os-cloud devstack-admin --os-region "$REGION_NAME" 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
+        _neutron_set_router_id
+    fi
+}
+
+# Configure neutron router for IPv6 public access
+function _neutron_configure_router_v6 {
+    neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-interface-add $ROUTER_ID $IPV6_SUBNET_ID
+    # Create a public subnet on the external network
+    local ipv6_id_and_ext_gw_ip
+    ipv6_id_and_ext_gw_ip=$(_neutron_create_public_subnet_v6 $EXT_NET_ID)
+    local ipv6_ext_gw_ip
+    ipv6_ext_gw_ip=$(echo $ipv6_id_and_ext_gw_ip | get_field 2)
+    local ipv6_pub_subnet_id
+    ipv6_pub_subnet_id=$(echo $ipv6_id_and_ext_gw_ip | get_field 5)
+
+    # If the external network has not already been set as the default router
+    # gateway when configuring an IPv4 public subnet, do so now
+    if [[ "$IP_VERSION" == "6" ]]; then
+        neutron --os-cloud devstack-admin --os-region "$REGION_NAME" router-gateway-set $ROUTER_ID $EXT_NET_ID
+    fi
+
+    # This logic is specific to using the l3-agent for layer 3
+    if is_service_enabled q-l3; then
+        # Ensure IPv6 forwarding is enabled on the host
+        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 --os-cloud devstack-admin --os-region "$REGION_NAME" 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; then
+            local ext_gw_interface
+            ext_gw_interface=$(_neutron_get_ext_gw_interface)
+            local ipv6_cidr_len=${IPV6_PUBLIC_RANGE#*/}
+
+            # Configure interface for public bridge
+            sudo ip -6 addr add $ipv6_ext_gw_ip/$ipv6_cidr_len dev $ext_gw_interface
+            sudo ip -6 route replace $FIXED_RANGE_V6 via $IPV6_ROUTER_GW_IP dev $ext_gw_interface
+        fi
+        _neutron_set_router_id
+    fi
+}
+
+function is_provider_network {
+    if [ "$Q_USE_PROVIDER_NETWORKING" == "True" ]; then
+        return 0
+    fi
+    return 1
+}
diff --git a/lib/neutron_plugins/services/vpn b/lib/neutron_plugins/services/vpn
deleted file mode 100644
index e790913..0000000
--- a/lib/neutron_plugins/services/vpn
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/bash
-
-# Neutron VPN plugin
-# ---------------------------
-
-# Save trace setting
-_XTRACE_NEUTRON_VPN=$(set +o | grep xtrace)
-set +o xtrace
-
-
-AGENT_VPN_BINARY="$NEUTRON_BIN_DIR/neutron-vpn-agent"
-VPN_PLUGIN=${VPN_PLUGIN:-"neutron_vpnaas.services.vpn.plugin.VPNDriverPlugin"}
-IPSEC_PACKAGE=${IPSEC_PACKAGE:-"openswan"}
-
-function neutron_vpn_install_agent_packages {
-    install_package $IPSEC_PACKAGE
-    if is_ubuntu && [[ "$IPSEC_PACKAGE" == "strongswan" ]]; then
-        sudo ln -sf /etc/apparmor.d/usr.lib.ipsec.charon /etc/apparmor.d/disable/
-        sudo ln -sf /etc/apparmor.d/usr.lib.ipsec.stroke /etc/apparmor.d/disable/
-        # NOTE: Due to https://bugs.launchpad.net/ubuntu/+source/apparmor/+bug/1387220
-        # one must use 'sudo start apparmor ACTION=reload' for Ubuntu 14.10
-        restart_service apparmor
-    fi
-}
-
-function neutron_vpn_configure_common {
-    _neutron_service_plugin_class_add $VPN_PLUGIN
-    _neutron_deploy_rootwrap_filters $NEUTRON_VPNAAS_DIR
-}
-
-function neutron_vpn_configure_agent {
-    # 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
-            iniset $Q_VPN_CONF_FILE strongswan default_config_area /usr/share/strongswan/templates/config/strongswan.d
-        fi
-    else
-        iniset_multiline $Q_VPN_CONF_FILE vpnagent vpn_device_driver neutron_vpnaas.services.vpn.device_drivers.ipsec.OpenSwanDriver
-    fi
-}
-
-function neutron_vpn_stop {
-    local ipsec_data_dir=$DATA_DIR/neutron/ipsec
-    local pids
-    if [ -d $ipsec_data_dir ]; then
-        pids=$(find $ipsec_data_dir -name 'pluto.pid' -exec cat {} \;)
-    fi
-    if [ -n "$pids" ]; then
-        sudo kill $pids
-    fi
-    stop_process q-vpn
-}
-
-# Restore xtrace
-$_XTRACE_NEUTRON_VPN
diff --git a/lib/nova b/lib/nova
index 1b3d086..de898b2 100644
--- a/lib/nova
+++ b/lib/nova
@@ -59,11 +59,6 @@
 
 NOVA_API_PASTE_INI=${NOVA_API_PASTE_INI:-$NOVA_CONF_DIR/api-paste.ini}
 
-# NOVA_V2_LEGACY defines whether we force the Nova v2.0 enpoint onto
-# the Nova v2.0 legacy code base. Remove this option once the Nova
-# v2.0 legacy codebase is removed.
-NOVA_V2_LEGACY=$(trueorfalse False NOVA_V2_LEGACY)
-
 if is_suse; then
     NOVA_WSGI_DIR=${NOVA_WSGI_DIR:-/srv/www/htdocs/nova}
 else
@@ -311,13 +306,6 @@
     if [[ "$ENABLED_SERVICES" =~ "n-api" ]]; then
         # Get the sample configuration file in place
         cp $NOVA_DIR/etc/nova/api-paste.ini $NOVA_CONF_DIR
-
-        # For setting up an environment where v2.0 is running on the
-        # v2.0 legacy code base.
-        if [[ "$NOVA_V2_LEGACY" == "True" ]]; then
-            sed -i s@"^/v2: openstack_compute_api_v21_legacy_v2_compatible$"@"/v2: openstack_compute_api_legacy_v2"@ \
-                "$NOVA_API_PASTE_INI"
-        fi
     fi
 
     if is_service_enabled n-cpu; then
@@ -429,9 +417,9 @@
         get_or_create_endpoint \
             "compute" \
             "$REGION_NAME" \
-            "$nova_api_url/v2.1/\$(project_id)s" \
-            "$nova_api_url/v2.1/\$(project_id)s" \
-            "$nova_api_url/v2.1/\$(project_id)s"
+            "$nova_api_url/v2.1" \
+            "$nova_api_url/v2.1" \
+            "$nova_api_url/v2.1"
     fi
 
     if is_service_enabled n-api; then
@@ -439,7 +427,7 @@
         if is_service_enabled swift; then
             # Nova needs ResellerAdmin role to download images when accessing
             # swift through the s3 api.
-            get_or_add_user_project_role ResellerAdmin nova $SERVICE_PROJECT_NAME
+            get_or_add_user_project_role ResellerAdmin nova $SERVICE_PROJECT_NAME $SERVICE_DOMAIN_NAME $SERVICE_DOMAIN_NAME
         fi
     fi
 
@@ -466,7 +454,7 @@
     if [ "$NOVA_ALLOW_MOVE_TO_SAME_HOST" == "True" ]; then
         iniset $NOVA_CONF DEFAULT allow_resize_to_same_host "True"
     fi
-    iniset $NOVA_CONF DEFAULT api_paste_config "$NOVA_API_PASTE_INI"
+    iniset $NOVA_CONF wsgi api_paste_config "$NOVA_API_PASTE_INI"
     iniset $NOVA_CONF DEFAULT rootwrap_config "$NOVA_CONF_DIR/rootwrap.conf"
     iniset $NOVA_CONF DEFAULT scheduler_driver "$SCHEDULER"
     iniset $NOVA_CONF DEFAULT scheduler_default_filters "$FILTERS"
@@ -604,6 +592,9 @@
     if [[ "$NOVA_BACKEND" == "LVM" ]]; then
         iniset $NOVA_CONF libvirt images_type "lvm"
         iniset $NOVA_CONF libvirt images_volume_group $DEFAULT_VOLUME_GROUP_NAME
+        if isset LVM_VOLUME_CLEAR; then
+            iniset $NOVA_CONF libvirt volume_clear "$LVM_VOLUME_CLEAR"
+        fi
     fi
 
     if is_ssl_enabled_service glance || is_service_enabled tls-proxy; then
@@ -648,7 +639,7 @@
     if is_service_enabled n-cell; then
         cp $NOVA_CONF $NOVA_CELLS_CONF
         iniset $NOVA_CELLS_CONF database connection `database_connection_url $NOVA_CELLS_DB`
-        iniset $NOVA_CELLS_CONF DEFAULT rabbit_virtual_host child_cell
+        iniset $NOVA_CELLS_CONF oslo_messaging_rabbit rabbit_virtual_host child_cell
         iniset $NOVA_CELLS_CONF DEFAULT dhcpbridge_flagfile $NOVA_CELLS_CONF
         iniset $NOVA_CELLS_CONF cells enable True
         iniset $NOVA_CELLS_CONF cells cell_type compute
@@ -702,18 +693,18 @@
         recreate_database nova
 
         # Migrate nova database
-        $NOVA_BIN_DIR/nova-manage db sync
+        $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF db sync
 
         if is_service_enabled n-cell; then
             recreate_database $NOVA_CELLS_DB
         fi
 
         recreate_database $NOVA_API_DB
-        $NOVA_BIN_DIR/nova-manage api_db sync
+        $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF api_db sync
 
         # Run online migrations on the new databases
         # Needed for flavor conversion
-        $NOVA_BIN_DIR/nova-manage db online_data_migrations
+        $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF db online_data_migrations
     fi
 
     create_nova_cache_dir
@@ -932,6 +923,27 @@
     stop_nova_compute
 }
 
+# create_instance_types(): Create default flavors
+function create_flavors {
+    if is_service_enabled n-api; then
+        if ! openstack --os-region-name="$REGION_NAME" flavor list | grep -q ds512M; then
+            # Note that danms hates these flavors and apologizes for sdague
+            openstack --os-region-name="$REGION_NAME" flavor create --id c1 --ram 256 --disk 0 --vcpus 1 cirros256
+            openstack --os-region-name="$REGION_NAME" flavor create --id d1 --ram 512 --disk 5 --vcpus 1 ds512M
+            openstack --os-region-name="$REGION_NAME" flavor create --id d2 --ram 1024 --disk 10 --vcpus 1 ds1G
+            openstack --os-region-name="$REGION_NAME" flavor create --id d3 --ram 2048 --disk 10 --vcpus 2 ds2G
+            openstack --os-region-name="$REGION_NAME" flavor create --id d4 --ram 4096 --disk 20 --vcpus 4 ds4G
+        fi
+
+        if ! openstack --os-region-name="$REGION_NAME" flavor list | grep -q m1.tiny; then
+            openstack --os-region-name="$REGION_NAME" flavor create --id 1 --ram 512 --disk 1 --vcpus 1 m1.tiny
+            openstack --os-region-name="$REGION_NAME" flavor create --id 2 --ram 2048 --disk 20 --vcpus 1 m1.small
+            openstack --os-region-name="$REGION_NAME" flavor create --id 3 --ram 4096 --disk 40 --vcpus 2 m1.medium
+            openstack --os-region-name="$REGION_NAME" flavor create --id 4 --ram 8192 --disk 80 --vcpus 4 m1.large
+            openstack --os-region-name="$REGION_NAME" flavor create --id 5 --ram 16384 --disk 160 --vcpus 8 m1.xlarge
+        fi
+    fi
+}
 
 # Restore xtrace
 $_XTRACE_LIB_NOVA
diff --git a/lib/nova_plugins/hypervisor-ironic b/lib/nova_plugins/hypervisor-ironic
index 43e7797..c40427c 100644
--- a/lib/nova_plugins/hypervisor-ironic
+++ b/lib/nova_plugins/hypervisor-ironic
@@ -39,7 +39,7 @@
     configure_libvirt
     LIBVIRT_FIREWALL_DRIVER=${LIBVIRT_FIREWALL_DRIVER:-"nova.virt.firewall.NoopFirewallDriver"}
 
-    iniset $NOVA_CONF DEFAULT compute_driver nova.virt.ironic.IronicDriver
+    iniset $NOVA_CONF DEFAULT compute_driver ironic.IronicDriver
     iniset $NOVA_CONF DEFAULT firewall_driver $LIBVIRT_FIREWALL_DRIVER
     iniset $NOVA_CONF DEFAULT scheduler_host_manager ironic_host_manager
     iniset $NOVA_CONF DEFAULT ram_allocation_ratio 1.0
diff --git a/lib/nova_plugins/hypervisor-xenserver b/lib/nova_plugins/hypervisor-xenserver
index 3eb9149..e7f1e87 100644
--- a/lib/nova_plugins/hypervisor-xenserver
+++ b/lib/nova_plugins/hypervisor-xenserver
@@ -29,7 +29,8 @@
 # Allow ``build_domU.sh`` to specify the flat network bridge via kernel args
 FLAT_NETWORK_BRIDGE_DEFAULT=$(sed -e 's/.* flat_network_bridge=\([[:alnum:]]*\).*$/\1/g' /proc/cmdline)
 if is_service_enabled neutron; then
-    XEN_INTEGRATION_BRIDGE=$(sed -e 's/.* xen_integration_bridge=\([[:alnum:]]*\).*$/\1/g' /proc/cmdline)
+    XEN_INTEGRATION_BRIDGE_DEFAULT=$(sed -e 's/.* xen_integration_bridge=\([[:alnum:]]*\).*$/\1/g' /proc/cmdline)
+    XEN_INTEGRATION_BRIDGE=${XEN_INTEGRATION_BRIDGE:-$XEN_INTEGRATION_BRIDGE_DEFAULT}
 fi
 
 VNCSERVER_PROXYCLIENT_ADDRESS=${VNCSERVER_PROXYCLIENT_ADDRESS=169.254.0.1}
diff --git a/lib/swift b/lib/swift
index b2fe755..8cb94ef 100644
--- a/lib/swift
+++ b/lib/swift
@@ -149,6 +149,11 @@
 # Toggle for deploying Swift under HTTPD + mod_wsgi
 SWIFT_USE_MOD_WSGI=${SWIFT_USE_MOD_WSGI:-False}
 
+# A space-separated list of storage node IPs that
+# should be used to create the Swift rings
+SWIFT_STORAGE_IPS=${SWIFT_STORAGE_IPS:-}
+
+
 # Functions
 # ---------
 
@@ -495,21 +500,21 @@
         iniset ${swift_node_config} DEFAULT bind_ip ${SWIFT_SERVICE_LISTEN_ADDRESS}
     done
 
-    # Set new accounts in tempauth to match keystone tenant/user (to make testing easier)
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:tempauth user_swifttenanttest1_swiftusertest1 "testing .admin"
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:tempauth user_swifttenanttest2_swiftusertest2 "testing2 .admin"
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:tempauth user_swifttenanttest1_swiftusertest3 "testing3 .admin"
+    # Set new accounts in tempauth to match keystone project/user (to make testing easier)
+    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:tempauth user_swiftprojecttest1_swiftusertest1 "testing .admin"
+    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:tempauth user_swiftprojecttest2_swiftusertest2 "testing2 .admin"
+    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:tempauth user_swiftprojecttest1_swiftusertest3 "testing3 .admin"
 
     testfile=${SWIFT_CONF_DIR}/test.conf
     cp ${SWIFT_DIR}/test/sample.conf ${testfile}
 
     # Set accounts for functional tests
-    iniset ${testfile} func_test account swifttenanttest1
+    iniset ${testfile} func_test account swiftprojecttest1
     iniset ${testfile} func_test username swiftusertest1
     iniset ${testfile} func_test username3 swiftusertest3
-    iniset ${testfile} func_test account2 swifttenanttest2
+    iniset ${testfile} func_test account2 swiftprojecttest2
     iniset ${testfile} func_test username2 swiftusertest2
-    iniset ${testfile} func_test account4 swifttenanttest4
+    iniset ${testfile} func_test account4 swiftprojecttest4
     iniset ${testfile} func_test username4 swiftusertest4
     iniset ${testfile} func_test password4 testing4
     iniset ${testfile} func_test domain4 swift_test
@@ -603,13 +608,13 @@
 # since we want to make it compatible with tempauth which use
 # underscores for separators.
 
-# Tenant             User               Roles          Domain
-# ------------------------------------------------------------------
-# service            swift              service        default
-# swifttenanttest1   swiftusertest1     admin          default
-# swifttenanttest1   swiftusertest3     anotherrole    default
-# swifttenanttest2   swiftusertest2     admin          default
-# swifttenanttest4   swiftusertest4     admin          swift_test
+# Project             User               Roles          Domain
+# -------------------------------------------------------------------
+# service             swift              service        default
+# swiftprojecttest1   swiftusertest1     admin          default
+# swiftprojecttest1   swiftusertest3     anotherrole    default
+# swiftprojecttest2   swiftusertest2     admin          default
+# swiftprojecttest4   swiftusertest4     admin          swift_test
 
 function create_swift_accounts {
     # Defines specific passwords used by ``tools/create_userrc.sh``
@@ -635,43 +640,43 @@
         "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:$SWIFT_DEFAULT_BIND_PORT" \
         "$SWIFT_SERVICE_PROTOCOL://$SERVICE_HOST:$SWIFT_DEFAULT_BIND_PORT/v1/AUTH_\$(project_id)s"
 
-    local swift_tenant_test1
-    swift_tenant_test1=$(get_or_create_project swifttenanttest1 default)
-    die_if_not_set $LINENO swift_tenant_test1 "Failure creating swift_tenant_test1"
+    local swift_project_test1
+    swift_project_test1=$(get_or_create_project swiftprojecttest1 default)
+    die_if_not_set $LINENO swift_project_test1 "Failure creating swift_project_test1"
     SWIFT_USER_TEST1=$(get_or_create_user swiftusertest1 $swiftusertest1_password \
                         "default" "test@example.com")
     die_if_not_set $LINENO SWIFT_USER_TEST1 "Failure creating SWIFT_USER_TEST1"
-    get_or_add_user_project_role admin $SWIFT_USER_TEST1 $swift_tenant_test1
+    get_or_add_user_project_role admin $SWIFT_USER_TEST1 $swift_project_test1
 
     local swift_user_test3
     swift_user_test3=$(get_or_create_user swiftusertest3 $swiftusertest3_password \
                                 "default" "test3@example.com")
     die_if_not_set $LINENO swift_user_test3 "Failure creating swift_user_test3"
-    get_or_add_user_project_role $another_role $swift_user_test3 $swift_tenant_test1
+    get_or_add_user_project_role $another_role $swift_user_test3 $swift_project_test1
 
-    local swift_tenant_test2
-    swift_tenant_test2=$(get_or_create_project swifttenanttest2 default)
-    die_if_not_set $LINENO swift_tenant_test2 "Failure creating swift_tenant_test2"
+    local swift_project_test2
+    swift_project_test2=$(get_or_create_project swiftprojecttest2 default)
+    die_if_not_set $LINENO swift_project_test2 "Failure creating swift_project_test2"
 
     local swift_user_test2
     swift_user_test2=$(get_or_create_user swiftusertest2 $swiftusertest2_password \
                                 "default" "test2@example.com")
     die_if_not_set $LINENO swift_user_test2 "Failure creating swift_user_test2"
-    get_or_add_user_project_role admin $swift_user_test2 $swift_tenant_test2
+    get_or_add_user_project_role admin $swift_user_test2 $swift_project_test2
 
     local swift_domain
     swift_domain=$(get_or_create_domain swift_test 'Used for swift functional testing')
     die_if_not_set $LINENO swift_domain "Failure creating swift_test domain"
 
-    local swift_tenant_test4
-    swift_tenant_test4=$(get_or_create_project swifttenanttest4 $swift_domain)
-    die_if_not_set $LINENO swift_tenant_test4 "Failure creating swift_tenant_test4"
+    local swift_project_test4
+    swift_project_test4=$(get_or_create_project swiftprojecttest4 $swift_domain)
+    die_if_not_set $LINENO swift_project_test4 "Failure creating swift_project_test4"
 
     local swift_user_test4
     swift_user_test4=$(get_or_create_user swiftusertest4 $swiftusertest4_password \
                                 $swift_domain "test4@example.com")
     die_if_not_set $LINENO swift_user_test4 "Failure creating swift_user_test4"
-    get_or_add_user_project_role admin $swift_user_test4 $swift_tenant_test4
+    get_or_add_user_project_role admin $swift_user_test4 $swift_project_test4
 }
 
 # init_swift() - Initialize rings
@@ -693,14 +698,35 @@
         swift-ring-builder container.builder create ${SWIFT_PARTITION_POWER_SIZE} ${SWIFT_REPLICAS} 1
         swift-ring-builder account.builder create ${SWIFT_PARTITION_POWER_SIZE} ${SWIFT_REPLICAS} 1
 
-        for node_number in ${SWIFT_REPLICAS_SEQ}; do
-            swift-ring-builder object.builder add z${node_number}-${SWIFT_SERVICE_LOCAL_HOST}:$(( OBJECT_PORT_BASE + 10 * (node_number - 1) ))/sdb1 1
-            swift-ring-builder container.builder add z${node_number}-${SWIFT_SERVICE_LOCAL_HOST}:$(( CONTAINER_PORT_BASE + 10 * (node_number - 1) ))/sdb1 1
-            swift-ring-builder account.builder add z${node_number}-${SWIFT_SERVICE_LOCAL_HOST}:$(( ACCOUNT_PORT_BASE + 10 * (node_number - 1) ))/sdb1 1
-        done
-        swift-ring-builder object.builder rebalance
-        swift-ring-builder container.builder rebalance
-        swift-ring-builder account.builder rebalance
+        # The ring will be created on each node, and because the order of
+        # nodes is identical we can use a seed for rebalancing, making it
+        # possible to get a ring on each node that uses the same partition
+        # assignment.
+        if [[ -n $SWIFT_STORAGE_IPS ]]; then
+            local node_number
+            node_number=1
+
+            for node in ${SWIFT_STORAGE_IPS}; do
+                swift-ring-builder object.builder add z${node_number}-${node}:${OBJECT_PORT_BASE}/sdb1 1
+                swift-ring-builder container.builder add z${node_number}-${node}:${CONTAINER_PORT_BASE}/sdb1 1
+                swift-ring-builder account.builder add z${node_number}-${node}:${ACCOUNT_PORT_BASE}/sdb1 1
+                let "node_number=node_number+1"
+            done
+
+        else
+
+            for node_number in ${SWIFT_REPLICAS_SEQ}; do
+                swift-ring-builder object.builder add z${node_number}-${SWIFT_SERVICE_LOCAL_HOST}:$(( OBJECT_PORT_BASE + 10 * (node_number - 1) ))/sdb1 1
+                swift-ring-builder container.builder add z${node_number}-${SWIFT_SERVICE_LOCAL_HOST}:$(( CONTAINER_PORT_BASE + 10 * (node_number - 1) ))/sdb1 1
+                swift-ring-builder account.builder add z${node_number}-${SWIFT_SERVICE_LOCAL_HOST}:$(( ACCOUNT_PORT_BASE + 10 * (node_number - 1) ))/sdb1 1
+            done
+        fi
+
+        # We use a seed for rebalancing. Doing this allows us to create
+        # identical rings on multiple nodes if SWIFT_STORAGE_IPS is the same
+        swift-ring-builder object.builder rebalance 42
+        swift-ring-builder container.builder rebalance 42
+        swift-ring-builder account.builder rebalance 42
     } && popd >/dev/null
 
     # Create cache dir
@@ -820,7 +846,9 @@
     # note we are using swift credentials!
     OS_USERNAME=swift \
     OS_PASSWORD=$SERVICE_PASSWORD \
+    OS_USER_DOMAIN_NAME=$SERVICE_DOMAIN_NAME \
     OS_PROJECT_NAME=$SERVICE_PROJECT_NAME \
+    OS_PROJECT_DOMAIN_NAME=$SERVICE_DOMAIN_NAME \
     openstack object store account \
         set --property "Temp-URL-Key=$SWIFT_TEMPURL_KEY"
 }
diff --git a/lib/tempest b/lib/tempest
index d8790f8..cce541c 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -16,7 +16,6 @@
 #   - ``BASE_SQL_CONN`` ``lib/database`` declares
 #   - ``PUBLIC_NETWORK_NAME``
 #   - ``Q_ROUTER_NAME``
-#   - ``Q_L3_ENABLED``
 #   - ``VIRT_DRIVER``
 #   - ``LIBVIRT_TYPE``
 #   - ``KEYSTONE_SERVICE_PROTOCOL``, ``KEYSTONE_SERVICE_HOST`` from lib/keystone
@@ -45,8 +44,6 @@
 # --------
 
 # Set up default directories
-GITDIR["tempest-lib"]=$DEST/tempest-lib
-
 TEMPEST_DIR=$DEST/tempest
 TEMPEST_CONFIG_DIR=${TEMPEST_CONFIG_DIR:-$TEMPEST_DIR/etc}
 TEMPEST_CONFIG=$TEMPEST_CONFIG_DIR/tempest.conf
@@ -66,6 +63,10 @@
 # have tempest installed in DevStack by default.
 INSTALL_TEMPEST=${INSTALL_TEMPEST:-"True"}
 
+# This variable is passed directly to pip install inside the common tox venv
+# that is created
+TEMPEST_PLUGINS=${TEMPEST_PLUGINS:-0}
+
 # Cinder/Volume variables
 TEMPEST_VOLUME_DRIVER=${TEMPEST_VOLUME_DRIVER:-default}
 TEMPEST_DEFAULT_VOLUME_VENDOR="Open Source"
@@ -182,8 +183,6 @@
     local admin_username=${ADMIN_USERNAME:-admin}
     local admin_project_name=${ADMIN_TENANT_NAME:-admin}
     local admin_domain_name=${ADMIN_DOMAIN_NAME:-Default}
-    local tempest_username=${TEMPEST_USERNAME:-demo}
-    local tempest_project_name=${TEMPEST_TENANT_NAME:-demo}
     local alt_username=${ALT_USERNAME:-alt_demo}
     local alt_project_name=${ALT_TENANT_NAME:-alt_demo}
     local admin_project_id
@@ -239,7 +238,7 @@
 
     ssh_connect_method=${TEMPEST_SSH_CONNECT_METHOD:-$ssh_connect_method}
 
-    if [ "$Q_L3_ENABLED" = "True" ]; then
+    if is_service_enabled q-l3; then
         public_network_id=$(neutron net-list | grep $PUBLIC_NETWORK_NAME | \
             awk '{print $2}')
     fi
@@ -317,44 +316,6 @@
     fi
 
     # Compute Features
-    # Run ``verify_tempest_config -ur`` to retrieve enabled extensions on API endpoints
-    # NOTE(mtreinish): This must be done after auth settings are added to the tempest config
-    local tmp_cfg_file
-    tmp_cfg_file=$(mktemp)
-    cd $TEMPEST_DIR
-    if [[ "$OFFLINE" != "True" ]]; then
-        tox -revenv --notest
-    fi
-
-    # Auth
-    iniset $TEMPEST_CONFIG auth tempest_roles "Member"
-    if [[ $TEMPEST_USE_TEST_ACCOUNTS == "True" ]]; then
-        if [[ $TEMPEST_HAS_ADMIN == "True" ]]; then
-            tempest-account-generator -c $TEMPEST_CONFIG --os-username $admin_username --os-password "$password" --os-tenant-name $admin_project_name -r $TEMPEST_CONCURRENCY --with-admin etc/accounts.yaml
-        else
-            tempest-account-generator -c $TEMPEST_CONFIG --os-username $admin_username --os-password "$password" --os-tenant-name $admin_project_name -r $TEMPEST_CONCURRENCY etc/accounts.yaml
-        fi
-        iniset $TEMPEST_CONFIG auth use_dynamic_credentials False
-        iniset $TEMPEST_CONFIG auth test_accounts_file "etc/accounts.yaml"
-    elif [[ $TEMPEST_HAS_ADMIN == "False" ]]; then
-        iniset $TEMPEST_CONFIG auth use_dynamic_credentials ${TEMPEST_ALLOW_TENANT_ISOLATION:-False}
-
-    else
-        iniset $TEMPEST_CONFIG auth use_dynamic_credentials ${TEMPEST_ALLOW_TENANT_ISOLATION:-True}
-    fi
-
-    # NOTE(mtreinish): Respect constraints on tempest verify-config venv
-    tox -evenv -- pip install -c $REQUIREMENTS_DIR/upper-constraints.txt -r requirements.txt
-    tox -evenv -- tempest verify-config -uro $tmp_cfg_file
-
-    local compute_api_extensions=${COMPUTE_API_EXTENSIONS:-"all"}
-    if [[ ! -z "$DISABLE_COMPUTE_API_EXTENSIONS" ]]; then
-        # Enabled extensions are either the ones explicitly specified or those available on the API endpoint
-        compute_api_extensions=${COMPUTE_API_EXTENSIONS:-$(iniget $tmp_cfg_file compute-feature-enabled api_extensions | tr -d " ")}
-        # Remove disabled extensions
-        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.
@@ -369,21 +330,20 @@
         tempest_compute_max_microversion=None
     fi
     if [ "$tempest_compute_min_microversion" == "None" ]; then
-        inicomment $TEMPEST_CONFIG compute-feature-enabled min_microversion
+        inicomment $TEMPEST_CONFIG compute min_microversion
     else
-        iniset $TEMPEST_CONFIG compute-feature-enabled min_microversion $tempest_compute_min_microversion
+        iniset $TEMPEST_CONFIG compute min_microversion $tempest_compute_min_microversion
     fi
     if [ "$tempest_compute_max_microversion" == "None" ]; then
-        inicomment $TEMPEST_CONFIG compute-feature-enabled max_microversion
+        inicomment $TEMPEST_CONFIG compute max_microversion
     else
-        iniset $TEMPEST_CONFIG compute-feature-enabled max_microversion $tempest_compute_max_microversion
+        iniset $TEMPEST_CONFIG compute 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
     iniset $TEMPEST_CONFIG compute-feature-enabled block_migration_for_live_migration ${USE_BLOCK_MIGRATION_FOR_LIVE_MIGRATION:-False}
-    iniset $TEMPEST_CONFIG compute-feature-enabled api_extensions $compute_api_extensions
     # TODO(mriedem): Remove the preserve_ports flag when Juno is end of life.
     iniset $TEMPEST_CONFIG compute-feature-enabled preserve_ports True
     # TODO(gilliard): Remove the live_migrate_paused_instances flag when Juno is end of life.
@@ -398,6 +358,8 @@
         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
+        # Cells v1 doesn't support the rescue/unrescue tests in Tempest
+        iniset $TEMPEST_CONFIG compute-feature-enabled rescue False
 
         if  [[ -z "$DEFAULT_INSTANCE_TYPE" ]]; then
             # Cells supports resize but does not currently work with devstack
@@ -411,24 +373,20 @@
 
     # Network
     iniset $TEMPEST_CONFIG network api_version 2.0
-    iniset $TEMPEST_CONFIG network tenant_networks_reachable false
+    iniset $TEMPEST_CONFIG network project_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"
     iniset $TEMPEST_CONFIG network-feature-enabled ipv6 "$IPV6_ENABLED"
     iniset $TEMPEST_CONFIG network-feature-enabled ipv6_subnet_attributes "$IPV6_SUBNET_ATTRIBUTES_ENABLED"
 
-    local network_api_extensions=${NETWORK_API_EXTENSIONS:-"all"}
-    if [[ ! -z "$DISABLE_NETWORK_API_EXTENSIONS" ]]; then
-        # Enabled extensions are either the ones explicitly specified or those available on the API endpoint
-        network_api_extensions=${NETWORK_API_EXTENSIONS:-$(iniget $tmp_cfg_file network-feature-enabled api_extensions | tr -d " ")}
-        # Remove disabled extensions
-        network_api_extensions=$(remove_disabled_extensions $network_api_extensions $DISABLE_NETWORK_API_EXTENSIONS)
-    fi
-    iniset $TEMPEST_CONFIG network-feature-enabled api_extensions $network_api_extensions
-
     # Orchestration Tests
     if is_service_enabled heat; then
+        # Though this is not needed by heat, some tempest tests explicitly
+        # try to set this role. Removing them from the tempest tests breaks
+        # some non-devstack CIs.
+        get_or_create_role "heat_stack_owner"
+
         if [[ ! -z "$HEAT_CFN_IMAGE_URL" ]]; then
             iniset $TEMPEST_CONFIG orchestration image_ref $(basename "${HEAT_CFN_IMAGE_URL%.*}")
         fi
@@ -442,7 +400,7 @@
             iniset $TEMPEST_CONFIG orchestration instance_type "m1.heat"
         fi
         iniset $TEMPEST_CONFIG orchestration build_timeout 900
-        iniset $TEMPEST_CONFIG orchestration stack_owner_role "_member_"
+        iniset $TEMPEST_CONFIG orchestration stack_owner_role "heat_stack_owner"
     fi
 
     # Scenario
@@ -459,16 +417,6 @@
     # Telemetry
     iniset $TEMPEST_CONFIG telemetry-feature-enabled events "True"
 
-    # Object Store
-    local object_storage_api_extensions=${OBJECT_STORAGE_API_EXTENSIONS:-"all"}
-    if [[ ! -z "$DISABLE_OBJECT_STORAGE_API_EXTENSIONS" ]]; then
-        # Enabled extensions are either the ones explicitly specified or those available on the API endpoint
-        object_storage_api_extensions=${OBJECT_STORAGE_API_EXTENSIONS:-$(iniget $tmp_cfg_file object-storage-feature-enabled discoverable_apis | tr -d " ")}
-        # Remove disabled extensions
-        object_storage_api_extensions=$(remove_disabled_extensions $object_storage_api_extensions $DISABLE_STORAGE_API_EXTENSIONS)
-    fi
-    iniset $TEMPEST_CONFIG object-storage-feature-enabled discoverable_apis $object_storage_api_extensions
-
     # Validation
     iniset $TEMPEST_CONFIG validation run_validation ${TEMPEST_RUN_VALIDATION:-False}
     iniset $TEMPEST_CONFIG validation ip_version_for_ssh 4
@@ -481,15 +429,8 @@
     iniset $TEMPEST_CONFIG volume-feature-enabled incremental_backup_force True
     # TODO(ynesenenko): Remove the volume_services flag when Liberty and Kilo will correct work with host info.
     iniset $TEMPEST_CONFIG volume-feature-enabled volume_services True
-
-    local volume_api_extensions=${VOLUME_API_EXTENSIONS:-"all"}
-    if [[ ! -z "$DISABLE_VOLUME_API_EXTENSIONS" ]]; then
-        # Enabled extensions are either the ones explicitly specified or those available on the API endpoint
-        volume_api_extensions=${VOLUME_API_EXTENSIONS:-$(iniget $tmp_cfg_file volume-feature-enabled api_extensions | tr -d " ")}
-        # Remove disabled extensions
-        volume_api_extensions=$(remove_disabled_extensions $volume_api_extensions $DISABLE_VOLUME_API_EXTENSIONS)
-    fi
-    iniset $TEMPEST_CONFIG volume-feature-enabled api_extensions $volume_api_extensions
+    # TODO(ameade): Remove the api_v3 flag when Mitaka and Liberty are end of life.
+    iniset $TEMPEST_CONFIG volume-feature-enabled api_v3 True
 
     if ! is_service_enabled c-bak; then
         iniset $TEMPEST_CONFIG volume-feature-enabled backup False
@@ -571,24 +512,80 @@
         iniset $TEMPEST_CONFIG service_available cinder "False"
     fi
 
+    # Run tempest configuration utilities. This must be done last during configuration to
+    # ensure as complete a config as possible already exists
+
+    # NOTE(mtreinish): Respect constraints on tempest verify-config venv
+    local tmp_cfg_file
+    tmp_cfg_file=$(mktemp)
+    cd $TEMPEST_DIR
+    if [[ "$OFFLINE" != "True" ]]; then
+        tox -revenv-tempest --notest
+    fi
+    tox -evenv-tempest -- pip install -c $REQUIREMENTS_DIR/upper-constraints.txt -r requirements.txt
+
+    # Auth:
+    iniset $TEMPEST_CONFIG auth tempest_roles "Member"
+    if [[ $TEMPEST_USE_TEST_ACCOUNTS == "True" ]]; then
+        if [[ $TEMPEST_HAS_ADMIN == "True" ]]; then
+            tox -evenv-tempest -- tempest-account-generator -c $TEMPEST_CONFIG --os-username $admin_username --os-password "$password" --os-tenant-name $admin_project_name -r $TEMPEST_CONCURRENCY --with-admin etc/accounts.yaml
+        else
+            tox -evenv-tempest -- tempest-account-generator -c $TEMPEST_CONFIG --os-username $admin_username --os-password "$password" --os-tenant-name $admin_project_name -r $TEMPEST_CONCURRENCY etc/accounts.yaml
+        fi
+        iniset $TEMPEST_CONFIG auth use_dynamic_credentials False
+        iniset $TEMPEST_CONFIG auth test_accounts_file "etc/accounts.yaml"
+    elif [[ $TEMPEST_HAS_ADMIN == "False" ]]; then
+        iniset $TEMPEST_CONFIG auth use_dynamic_credentials ${TEMPEST_ALLOW_TENANT_ISOLATION:-False}
+
+    else
+        iniset $TEMPEST_CONFIG auth use_dynamic_credentials ${TEMPEST_ALLOW_TENANT_ISOLATION:-True}
+    fi
+
+    # API Extensions
+    # Run ``verify_tempest_config -ur`` to retrieve enabled extensions on API endpoints
+    # NOTE(mtreinish): This must be done after auth settings are added to the tempest config
+    tox -evenv -- tempest verify-config -uro $tmp_cfg_file
+    # Nova API extensions
+    local compute_api_extensions=${COMPUTE_API_EXTENSIONS:-"all"}
+    if [[ ! -z "$DISABLE_COMPUTE_API_EXTENSIONS" ]]; then
+        # Enabled extensions are either the ones explicitly specified or those available on the API endpoint
+        compute_api_extensions=${COMPUTE_API_EXTENSIONS:-$(iniget $tmp_cfg_file compute-feature-enabled api_extensions | tr -d " ")}
+        # Remove disabled extensions
+        compute_api_extensions=$(remove_disabled_extensions $compute_api_extensions $DISABLE_COMPUTE_API_EXTENSIONS)
+    fi
+    iniset $TEMPEST_CONFIG compute-feature-enabled api_extensions $compute_api_extensions
+    # Neutron API Extensions
+    local network_api_extensions=${NETWORK_API_EXTENSIONS:-"all"}
+    if [[ ! -z "$DISABLE_NETWORK_API_EXTENSIONS" ]]; then
+        # Enabled extensions are either the ones explicitly specified or those available on the API endpoint
+        network_api_extensions=${NETWORK_API_EXTENSIONS:-$(iniget $tmp_cfg_file network-feature-enabled api_extensions | tr -d " ")}
+        # Remove disabled extensions
+        network_api_extensions=$(remove_disabled_extensions $network_api_extensions $DISABLE_NETWORK_API_EXTENSIONS)
+    fi
+    iniset $TEMPEST_CONFIG network-feature-enabled api_extensions $network_api_extensions
+    # Swift API Extensions
+    local object_storage_api_extensions=${OBJECT_STORAGE_API_EXTENSIONS:-"all"}
+    if [[ ! -z "$DISABLE_OBJECT_STORAGE_API_EXTENSIONS" ]]; then
+        # Enabled extensions are either the ones explicitly specified or those available on the API endpoint
+        object_storage_api_extensions=${OBJECT_STORAGE_API_EXTENSIONS:-$(iniget $tmp_cfg_file object-storage-feature-enabled discoverable_apis | tr -d " ")}
+        # Remove disabled extensions
+        object_storage_api_extensions=$(remove_disabled_extensions $object_storage_api_extensions $DISABLE_STORAGE_API_EXTENSIONS)
+    fi
+    iniset $TEMPEST_CONFIG object-storage-feature-enabled discoverable_apis $object_storage_api_extensions
+    # Cinder API Extensions
+    local volume_api_extensions=${VOLUME_API_EXTENSIONS:-"all"}
+    if [[ ! -z "$DISABLE_VOLUME_API_EXTENSIONS" ]]; then
+        # Enabled extensions are either the ones explicitly specified or those available on the API endpoint
+        volume_api_extensions=${VOLUME_API_EXTENSIONS:-$(iniget $tmp_cfg_file volume-feature-enabled api_extensions | tr -d " ")}
+        # Remove disabled extensions
+        volume_api_extensions=$(remove_disabled_extensions $volume_api_extensions $DISABLE_VOLUME_API_EXTENSIONS)
+    fi
+    iniset $TEMPEST_CONFIG volume-feature-enabled api_extensions $volume_api_extensions
+
     # Restore IFS
     IFS=$ifs
 }
 
-
-# install_tempest_lib() - Collect source, prepare, and install ``tempest-lib``
-function install_tempest_lib {
-    if use_library_from_git "tempest-lib"; then
-        git_clone_by_name "tempest-lib"
-        setup_dev_lib "tempest-lib"
-        # NOTE(mtreinish) For testing ``tempest-lib`` from git with Tempest we need to
-        # put the git version of ``tempest-lib`` in the Tempest job's tox venv
-        export PIP_VIRTUAL_ENV=${PROJECT_VENV["tempest"]}
-        setup_dev_lib "tempest-lib"
-        unset PIP_VIRTUAL_ENV
-    fi
-}
-
 # install_tempest() - Collect source and prepare
 function install_tempest {
     git_clone $TEMPEST_REPO $TEMPEST_DIR $TEMPEST_BRANCH
@@ -598,9 +595,11 @@
     # NOTE(mtreinish) Respect constraints in the tempest full venv, things that
     # are using a tox job other than full will not be respecting constraints but
     # running pip install -U on tempest requirements
-    $TEMPEST_DIR/.tox/full/bin/pip install -c $REQUIREMENTS_DIR/upper-constraints.txt -r requirements.txt
-    PROJECT_VENV["tempest"]=${TEMPEST_DIR}/.tox/full
-    install_tempest_lib
+    $TEMPEST_DIR/.tox/tempest/bin/pip install -c $REQUIREMENTS_DIR/upper-constraints.txt -r requirements.txt
+    PROJECT_VENV["tempest"]=${TEMPEST_DIR}/.tox/tempest
+    if [[ $TEMPEST_PLUGINS != 0 ]] ; then
+        tox -evenv-tempest -- pip install $TEMPEST_PLUGINS
+    fi
     popd
 }
 
diff --git a/lib/template b/lib/template
index 08d10bb..b92fb40 100644
--- a/lib/template
+++ b/lib/template
@@ -35,8 +35,8 @@
 XXX_CONF_DIR=/etc/XXXX
 
 
-# Entry Points
-# ------------
+# Functions
+# ---------
 
 # Test if any XXXX services are enabled
 # is_XXXX_enabled
@@ -62,6 +62,11 @@
     :
 }
 
+# create_XXXX_accounts() - Create required service accounts
+function create_XXXX_accounts {
+    :
+}
+
 # init_XXXX() - Initialize databases, etc.
 function init_XXXX {
     # clean up from previous (possibly aborted) runs
diff --git a/pkg/elasticsearch.sh b/pkg/elasticsearch.sh
index 9c4f6f7..856eaff 100755
--- a/pkg/elasticsearch.sh
+++ b/pkg/elasticsearch.sh
@@ -10,7 +10,7 @@
 
 # Package source and version, all pkg files are expected to have
 # something like this, as well as a way to override them.
-ELASTICSEARCH_VERSION=${ELASTICSEARCH_VERSION:-1.4.2}
+ELASTICSEARCH_VERSION=${ELASTICSEARCH_VERSION:-1.7.5}
 ELASTICSEARCH_BASEURL=${ELASTICSEARCH_BASEURL:-https://download.elasticsearch.org/elasticsearch/elasticsearch}
 
 # Elastic search actual implementation
diff --git a/stack.sh b/stack.sh
index 793b7dc..21f7f35 100755
--- a/stack.sh
+++ b/stack.sh
@@ -185,7 +185,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} =~ (trusty|vivid|wily|7.0|wheezy|sid|testing|jessie|f22|f23|rhel7|kvmibm1) ]]; then
+if [[ ! ${DISTRO} =~ (trusty|wily|xenial|7.0|wheezy|sid|testing|jessie|f22|f23|rhel7|kvmibm1) ]]; 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"
@@ -240,7 +240,6 @@
 # see them by forcing ``PATH``
 echo "Defaults:$STACK_USER secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE
 echo "Defaults:$STACK_USER !requiretty" >> $TEMPFILE
-echo "Defaults env_keep += PS4" >> $TEMPFILE
 chmod 0440 $TEMPFILE
 sudo chown root:root $TEMPFILE
 sudo mv $TEMPFILE /etc/sudoers.d/50_stack_sh
@@ -559,6 +558,7 @@
 source $TOP_DIR/lib/cinder
 source $TOP_DIR/lib/swift
 source $TOP_DIR/lib/heat
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 source $TOP_DIR/lib/ldap
 source $TOP_DIR/lib/dstat
@@ -1020,7 +1020,7 @@
 export OS_PASSWORD=$ADMIN_PASSWORD
 export OS_PROJECT_NAME=admin
 export OS_PROJECT_DOMAIN_ID=default
-export OS_REGION_NAME=$REGION_NAME
+export OS_REGION_NAME=$KEYSTONE_REGION_NAME
 
 EOF
 
@@ -1075,7 +1075,7 @@
 
     configure_neutron
     # Run init_neutron only on the node hosting the Neutron API server
-    if is_service_enabled $DATABASE_BACKENDS && is_service_enabled q-svc; then
+    if is_service_enabled $DATABASE_BACKENDS && is_service_enabled neutron; then
         init_neutron
     fi
 fi
@@ -1142,7 +1142,7 @@
 
     # Additional Nova configuration that is dependent on other services
     if is_service_enabled neutron; then
-        create_nova_conf_neutron
+        configure_neutron_nova
     elif is_service_enabled n-net; then
         create_nova_conf_nova_network
     fi
@@ -1208,9 +1208,9 @@
     done
 fi
 
-# Create a randomized default value for the keymgr's fixed_key
+# Create a randomized default value for the key manager's fixed_key
 if is_service_enabled nova; then
-    iniset $NOVA_CONF keymgr fixed_key $(generate_hex_string 32)
+    iniset $NOVA_CONF key_manager fixed_key $(generate_hex_string 32)
 fi
 
 # Launch the nova-api and wait for it to answer before continuing
@@ -1219,7 +1219,11 @@
     start_nova_api
 fi
 
-if is_service_enabled q-svc; then
+if is_service_enabled neutron-api; then
+    echo_summary "Starting Neutron"
+    start_neutron_api
+    # check_neutron_third_party_integration
+elif is_service_enabled q-svc; then
     echo_summary "Starting Neutron"
     start_neutron_service_and_check
     check_neutron_third_party_integration
@@ -1240,7 +1244,7 @@
 fi
 
 if is_service_enabled neutron; then
-    start_neutron_agents
+    start_neutron
 fi
 # Once neutron agents are started setup initial network elements
 if is_service_enabled q-svc && [[ "$NEUTRON_CREATE_INITIAL_NETWORKS" == "True" ]]; then
@@ -1248,9 +1252,11 @@
     create_neutron_initial_network
     setup_neutron_debug
 fi
+
 if is_service_enabled nova; then
     echo_summary "Starting Nova"
     start_nova
+    create_flavors
 fi
 if is_service_enabled cinder; then
     echo_summary "Starting Cinder"
diff --git a/stackrc b/stackrc
index 17d6047..4ba57c9 100644
--- a/stackrc
+++ b/stackrc
@@ -42,6 +42,12 @@
 # Specify region name Region
 REGION_NAME=${REGION_NAME:-RegionOne}
 
+# Specify name of region where identity service endpoint is registered.
+# When deploying multiple DevStack instances in different regions with shared
+# Keystone, set KEYSTONE_REGION_NAME to the region where Keystone is running
+# for DevStack instances which do not host Keystone.
+KEYSTONE_REGION_NAME=${KEYSTONE_REGION_NAME:-$REGION_NAME}
+
 # Specify which services to launch.  These generally correspond to
 # screen tabs. To change the default list, use the ``enable_service`` and
 # ``disable_service`` functions in ``local.conf``.
@@ -242,10 +248,6 @@
 NEUTRON_LBAAS_REPO=${NEUTRON_LBAAS_REPO:-${GIT_BASE}/openstack/neutron-lbaas.git}
 NEUTRON_LBAAS_BRANCH=${NEUTRON_LBAAS_BRANCH:-master}
 
-# neutron vpnaas service
-NEUTRON_VPNAAS_REPO=${NEUTRON_VPNAAS_REPO:-${GIT_BASE}/openstack/neutron-vpnaas.git}
-NEUTRON_VPNAAS_BRANCH=${NEUTRON_VPNAAS_BRANCH:-master}
-
 # compute service
 NOVA_REPO=${NOVA_REPO:-${GIT_BASE}/openstack/nova.git}
 NOVA_BRANCH=${NOVA_BRANCH:-master}
@@ -268,10 +270,6 @@
 TEMPEST_REPO=${TEMPEST_REPO:-${GIT_BASE}/openstack/tempest.git}
 TEMPEST_BRANCH=${TEMPEST_BRANCH:-master}
 
-# TODO(sdague): this should end up as a library component like below
-GITREPO["tempest-lib"]=${TEMPEST_LIB_REPO:-${GIT_BASE}/openstack/tempest-lib.git}
-GITBRANCH["tempest-lib"]=${TEMPEST_LIB_BRANCH:-master}
-
 
 ##############
 #
diff --git a/tests/test_libs_from_pypi.sh b/tests/test_libs_from_pypi.sh
index f01db6d..a979c34 100755
--- a/tests/test_libs_from_pypi.sh
+++ b/tests/test_libs_from_pypi.sh
@@ -31,7 +31,7 @@
 
 ALL_LIBS="python-novaclient oslo.config pbr oslo.context"
 ALL_LIBS+=" python-keystoneclient taskflow oslo.middleware pycadf"
-ALL_LIBS+=" python-glanceclient python-ironicclient tempest-lib"
+ALL_LIBS+=" python-glanceclient python-ironicclient"
 ALL_LIBS+=" oslo.messaging oslo.log cliff python-heatclient stevedore"
 ALL_LIBS+=" python-cinderclient glance_store oslo.concurrency oslo.db"
 ALL_LIBS+=" oslo.versionedobjects oslo.vmware keystonemiddleware"
diff --git a/tools/build_docs.sh b/tools/build_docs.sh
deleted file mode 100755
index 7dc492e..0000000
--- a/tools/build_docs.sh
+++ /dev/null
@@ -1,100 +0,0 @@
-#!/usr/bin/env bash
-
-# **build_docs.sh** - Build the docs for DevStack
-#
-# - Install shocco if not found on ``PATH`` and ``INSTALL_SHOCCO`` is set
-# - Clone ``MASTER_REPO`` branch ``MASTER_BRANCH``
-# - Re-creates ``doc/build/html`` directory from existing repo + new generated script docs
-
-# Usage:
-## build_docs.sh [-o <out-dir>]
-## -o <out-dir>     Write the static HTML output to <out-dir>
-##                  (Note that <out-dir> will be deleted and re-created to ensure it is clean)
-
-# Defaults
-# --------
-
-HTML_BUILD=doc/build/html
-
-# Keep track of the DevStack directory
-TOP_DIR=$(cd $(dirname "$0")/.. && pwd)
-
-# Uses this shocco branch: https://github.com/dtroyer/shocco/tree/rst_support
-SHOCCO=${SHOCCO:-shocco}
-if ! which shocco; then
-    if [[ ! -x $TOP_DIR/shocco/shocco ]]; then
-        if [[ -z "$INSTALL_SHOCCO" ]]; then
-            echo "shocco not found in \$PATH, please set environment variable SHOCCO"
-            exit 1
-        fi
-        echo "Installing local copy of shocco"
-        if ! which pygmentize; then
-            sudo pip install Pygments
-        fi
-        if ! which rst2html.py; then
-            sudo pip install docutils
-        fi
-        git clone -b rst_support https://github.com/dtroyer/shocco shocco
-        cd shocco
-        ./configure
-        make || exit
-        cd ..
-    fi
-    SHOCCO=$TOP_DIR/shocco/shocco
-fi
-
-# Process command-line args
-while getopts o: c; do
-    case $c in
-        o)  HTML_BUILD=$OPTARG
-            ;;
-    esac
-done
-shift `expr $OPTIND - 1`
-
-
-# Processing
-# ----------
-
-# Ensure build dir exists
-mkdir -p $HTML_BUILD
-
-# Get fully qualified dirs
-FQ_HTML_BUILD=$(cd $HTML_BUILD && pwd)
-
-# Insert automated bits
-GLOG=$(mktemp gitlogXXXX)
-echo "<ul>" >$GLOG
-git log \
-    --pretty=format:'            <li>%s - <em>Commit <a href="https://review.openstack.org/#q,%h,n,z">%h</a> %cd</em></li>' \
-    --date=short \
-    --since '6 months ago' | grep -v Merge >>$GLOG
-echo "</ul>" >>$GLOG
-sed -i~ -e $"/^.*%GIT_LOG%.*$/r $GLOG" -e $"/^.*%GIT_LOG%.*$/s/^.*%GIT_LOG%.*$//" $FQ_HTML_BUILD/changes.html
-rm -f $GLOG
-
-# Build list of scripts to process
-FILES=""
-for f in $(find . \( -name .git -o -name .tox \) -prune -o \( -type f -name \*.sh -not -path \*shocco/\* -print \)); do
-    echo $f
-    FILES+="$f "
-    mkdir -p $FQ_HTML_BUILD/`dirname $f`;
-    $SHOCCO $f > $FQ_HTML_BUILD/$f.html
-done
-for f in $(find functions functions-common inc lib pkg samples -type f -name \* ! -name *.md ! -name *.conf); do
-    echo $f
-    FILES+="$f "
-    mkdir -p $FQ_HTML_BUILD/`dirname $f`;
-    $SHOCCO $f > $FQ_HTML_BUILD/$f.html
-done
-echo "$FILES" >doc/files
-
-# Clean up or report the temp workspace
-if [[ -n REPO && -n $PUSH_REPO ]]; then
-    echo rm -rf $TMP_ROOT
-else
-    if [[ -z "$TMP_ROOT" ]]; then
-        TMP_ROOT="$(pwd)"
-    fi
-    echo "Built docs in $HTML_BUILD"
-fi
diff --git a/tools/create_userrc.sh b/tools/create_userrc.sh
index a7278e4..b6db5d1 100755
--- a/tools/create_userrc.sh
+++ b/tools/create_userrc.sh
@@ -22,6 +22,9 @@
     file=${file#$RC_DIR/}
     printf "%-40s " "$file:${called[1]}:${called[0]}"
 }
+# PS4 is exported to child shells and uses the 'short_source' function, so
+# export it so child shells have access to the 'short_source' function also.
+export -f short_source
 
 set -o xtrace
 
diff --git a/tools/fixup_stuff.sh b/tools/fixup_stuff.sh
index 15cb5a1..193a1f7 100755
--- a/tools/fixup_stuff.sh
+++ b/tools/fixup_stuff.sh
@@ -159,14 +159,6 @@
             pip_install --upgrade --force-reinstall requests
         fi
     fi
-
-    if [[ "$os_VENDOR" == "Fedora" ]] && [[ "$os_RELEASE" -ge "23" ]]; then
-        # work-around broken rabbitmq-server 3.6.1 packages
-        #  https://bugzilla.redhat.com/show_bug.cgi?id=1323610
-        # Will be removed when this bug is fixed.
-        sudo dnf -y install \
-             https://kojipkgs.fedoraproject.org/packages/rabbitmq-server/3.5.7/4.fc23/noarch/rabbitmq-server-3.5.7-4.fc23.noarch.rpm
-    fi
 fi
 
 # The version of pip(1.5.4) supported by python-virtualenv(1.11.4) has
diff --git a/tools/generate-devstack-plugins-list.py b/tools/generate-devstack-plugins-list.py
index aeec4dd..bbad1bf 100644
--- a/tools/generate-devstack-plugins-list.py
+++ b/tools/generate-devstack-plugins-list.py
@@ -44,16 +44,10 @@
     # stackforge, etc)
     return proj.startswith('openstack/')
 
-# Rather than returning a 404 for a nonexistent file, cgit delivers a
-# 0-byte response to a GET request.  It also does not provide a
-# Content-Length in a HEAD response, so the way we tell if a file exists
-# is to check the length of the entire GET response body.
+# Check if this project has a plugin file
 def has_devstack_plugin(proj):
     r = requests.get("https://git.openstack.org/cgit/%s/plain/devstack/plugin.sh" % proj)
-    if len(r.text) > 0:
-        return True
-    else:
-        False
+    return r.status_code == 200
 
 logging.debug("Getting project list from %s" % url)
 r = requests.get(url)
@@ -64,4 +58,4 @@
 
 for project in found_plugins:
     # strip of openstack/
-    print project[10:]
+    print(project[10:])
diff --git a/tools/generate-devstack-plugins-list.sh b/tools/generate-devstack-plugins-list.sh
old mode 100644
new mode 100755
index ea30cd5..95f1331
--- a/tools/generate-devstack-plugins-list.sh
+++ b/tools/generate-devstack-plugins-list.sh
@@ -78,6 +78,9 @@
     gitlink="https://git.openstack.org/cgit/openstack/${plugin}"
     printf "%-${name_col_len}s %s\n" "${plugin}" "\`${giturl} <${gitlink}>\`__"
 done
+
+title_underline ${name_col_len}
+
 printf "\n\n"
 
 if [[ -r data/devstack-plugins-registry.footer ]]; then
diff --git a/tools/worlddump.py b/tools/worlddump.py
index 345c2a3..e1ef544 100755
--- a/tools/worlddump.py
+++ b/tools/worlddump.py
@@ -14,6 +14,7 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
+
 """Dump the state of the world for post mortem."""
 
 import argparse
@@ -26,6 +27,16 @@
 import sys
 
 
+GMR_PROCESSES = (
+    'nova-compute',
+    'neutron-dhcp-agent',
+    'neutron-l3-agent',
+    'neutron-linuxbridge-agent',
+    'neutron-metadata-agent',
+    'neutron-openvswitch-agent',
+)
+
+
 def get_options():
     parser = argparse.ArgumentParser(
         description='Dump world state for debugging')
@@ -48,32 +59,39 @@
 
 
 def warn(msg):
-    print "WARN: %s" % msg
+    print("WARN: %s" % msg)
 
 
 def _dump_cmd(cmd):
-    print cmd
-    print "-" * len(cmd)
-    print
+    print(cmd)
+    print("-" * len(cmd))
+    print()
     try:
         subprocess.check_call(cmd, shell=True)
-        print
+        print()
     except subprocess.CalledProcessError as e:
-        print "*** Failed to run '%(cmd)s': %(err)s" % {'cmd': cmd, 'err': e}
+        print("*** Failed to run '%(cmd)s': %(err)s" % {'cmd': cmd, 'err': e})
 
 
 def _find_cmd(cmd):
     if not spawn.find_executable(cmd):
-        print "*** %s not found: skipping" % cmd
+        print("*** %s not found: skipping" % cmd)
         return False
     return True
 
 
 def _header(name):
-    print
-    print name
-    print "=" * len(name)
-    print
+    print()
+    print(name)
+    print("=" * len(name))
+    print()
+
+
+def _bridge_list():
+    process = subprocess.Popen(['sudo', 'ovs-vsctl', 'list-br'],
+                               stdout=subprocess.PIPE)
+    stdout, _ = process.communicate()
+    return stdout.split()
 
 
 # This method gets a max openflow version supported by openvswitch.
@@ -83,7 +101,7 @@
 #     Compiled Dec  9 2015 14:08:08
 #     OpenFlow versions 0x1:0x4
 #
-# The above shows that openvswitch supports from OpenFlow11 to OpenFlow13.
+# The above shows that openvswitch supports from OpenFlow10 to OpenFlow13.
 # This method gets max version searching 'OpenFlow versions 0x1:0x'.
 # And return a version value converted to an integer type.
 def _get_ofp_version():
@@ -109,7 +127,7 @@
             # if it doesn't look like an int, that's fine
             pass
 
-    print dfraw
+    print(dfraw)
 
 
 def ebtables_dump():
@@ -157,14 +175,11 @@
     if not _find_cmd('ovs-vsctl'):
         return
 
-    # NOTE(ihrachys): worlddump is used outside of devstack context (f.e. in
-    # grenade), so there is no single place to determine the bridge names from.
-    # Hardcode for now.
-    bridges = ('br-int', 'br-tun', 'br-ex')
+    bridges = _bridge_list()
     ofctl_cmds = ('show', 'dump-ports-desc', 'dump-ports', 'dump-flows')
     ofp_max = _get_ofp_version()
     vers = 'OpenFlow10'
-    for i in range(ofp_max + 1):
+    for i in range(1, ofp_max + 1):
         vers += ',OpenFlow1' + str(i)
     _dump_cmd("sudo ovs-vsctl show")
     for ofctl_cmd in ofctl_cmds:
@@ -187,23 +202,24 @@
             _dump_cmd("sudo cat %s" % fullpath)
 
 
-def guru_meditation_report():
-    _header("nova-compute Guru Meditation Report")
+def guru_meditation_reports():
+    for service in GMR_PROCESSES:
+        _header("%s Guru Meditation Report" % service)
 
-    try:
-        subprocess.check_call(["pgrep","nova-compute"])
-    except subprocess.CalledProcessError:
-        print "Skipping as nova-compute does not appear to be running"
-        return
+        try:
+            subprocess.check_call(['pgrep', '-f', service])
+        except subprocess.CalledProcessError:
+            print("Skipping as %s does not appear to be running" % service)
+            continue
 
-    _dump_cmd("kill -s USR2 `pgrep nova-compute`")
-    print "guru meditation report in nova-compute log"
+        _dump_cmd("killall -e -USR2 %s" % service)
+        print("guru meditation report in %s log" % service)
 
 
 def main():
     opts = get_options()
     fname = filename(opts.dir, opts.name)
-    print "World dumping... see %s for details" % fname
+    print("World dumping... see %s for details" % fname)
     sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
     with open(fname, 'w') as f:
         os.dup2(f.fileno(), sys.stdout.fileno())
@@ -214,7 +230,7 @@
         iptables_dump()
         ebtables_dump()
         compute_consoles()
-        guru_meditation_report()
+        guru_meditation_reports()
 
 
 if __name__ == '__main__':
diff --git a/tools/xen/README.md b/tools/xen/README.md
index 21090e5..7062ecb 100644
--- a/tools/xen/README.md
+++ b/tools/xen/README.md
@@ -170,3 +170,9 @@
     xe vm-import filename="$mountdir/$TEMPLATE_FILENAME"
     umount "$mountdir"
     rm -rf "$mountdir"
+
+### Migrate OpenStack DomU to another host
+
+Given you need to migrate your DomU with OpenStack installed to another host,
+you need to set `XEN_INTEGRATION_BRIDGE` in localrc if neutron network is used.
+It is the bridge for `XEN_INT_BRIDGE_OR_NET_NAME` network created in Dom0
diff --git a/tools/xen/install_os_domU.sh b/tools/xen/install_os_domU.sh
index 46ff0b6..8b97265 100755
--- a/tools/xen/install_os_domU.sh
+++ b/tools/xen/install_os_domU.sh
@@ -299,10 +299,10 @@
 # kernel parameter for DomU
 attach_network "$XEN_INT_BRIDGE_OR_NET_NAME"
 
-XEN_INTEGRATION_BRIDGE=$(bridge_for "$XEN_INT_BRIDGE_OR_NET_NAME")
+XEN_INTEGRATION_BRIDGE_DEFAULT=$(bridge_for "$XEN_INT_BRIDGE_OR_NET_NAME")
 append_kernel_cmdline \
     "$GUEST_NAME" \
-    "xen_integration_bridge=${XEN_INTEGRATION_BRIDGE}"
+    "xen_integration_bridge=${XEN_INTEGRATION_BRIDGE_DEFAULT}"
 
 FLAT_NETWORK_BRIDGE="${FLAT_NETWORK_BRIDGE:-$(bridge_for "$VM_BRIDGE_OR_NET_NAME")}"
 append_kernel_cmdline "$GUEST_NAME" "flat_network_bridge=${FLAT_NETWORK_BRIDGE}"
diff --git a/tox.ini b/tox.ini
index 4ec2939..55a06d0 100644
--- a/tox.ini
+++ b/tox.ini
@@ -12,12 +12,11 @@
 # against devstack, just set BASHATE_INSTALL_PATH=/path/... to your
 # modified bashate tree
 deps =
-   {env:BASHATE_INSTALL_PATH:bashate==0.5.0}
+   {env:BASHATE_INSTALL_PATH:bashate==0.5.1}
 whitelist_externals = bash
 commands = bash -c "find {toxinidir}             \
          -not \( -type d -name .?\* -prune \)    \
          -not \( -type d -name doc -prune \)     \
-         -not \( -type d -name shocco -prune \)  \
          -not \( -type f -name localrc -prune \) \
          -type f                                 \
          -not -name \*~                          \
@@ -48,7 +47,15 @@
 whitelist_externals = bash
 setenv =
   TOP_DIR={toxinidir}
-  INSTALL_SHOCCO=true
-commands = 
-	python setup.py build_sphinx
-	bash tools/build_docs.sh
+commands =
+  python setup.py build_sphinx
+
+[testenv:venv]
+deps =
+   pbr>=0.6,!=0.7,<1.0
+   sphinx>=1.1.2,<1.2
+   oslosphinx
+   blockdiag
+   sphinxcontrib-blockdiag
+   sphinxcontrib-nwdiag
+commands = {posargs}
diff --git a/unstack.sh b/unstack.sh
index 83703ec..a69b218 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -66,6 +66,7 @@
 source $TOP_DIR/lib/cinder
 source $TOP_DIR/lib/swift
 source $TOP_DIR/lib/heat
+source $TOP_DIR/lib/neutron
 source $TOP_DIR/lib/neutron-legacy
 source $TOP_DIR/lib/ldap
 source $TOP_DIR/lib/dstat