Merge "iniset_rpc_backend default section"
diff --git a/HACKING.rst b/HACKING.rst
index b3c82a3..4971db2 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -25,23 +25,63 @@
 __ lp_
 .. _lp: https://launchpad.net/~devstack
 
+The `Gerrit review
+queue <https://review.openstack.org/#/q/project:openstack-dev/devstack,n,z>`__
+is used for all commits.
+
 The primary script in DevStack is ``stack.sh``, which performs the bulk of the
 work for DevStack's use cases.  There is a subscript ``functions`` that contains
 generally useful shell functions and is used by a number of the scripts in
 DevStack.
 
-The ``lib`` directory contains sub-scripts for projects or packages that ``stack.sh``
-sources to perform much of the work related to those projects.  These sub-scripts
-contain configuration defaults and functions to configure, start and stop the project
-or package.  These variables and functions are also used by related projects,
-such as Grenade, to manage a DevStack installation.
-
 A number of additional scripts can be found in the ``tools`` directory that may
 be useful in supporting DevStack installations.  Of particular note are ``info.sh``
 to collect and report information about the installed system, and ``install_prereqs.sh``
 that handles installation of the prerequisite packages for DevStack.  It is
 suitable, for example, to pre-load a system for making a snapshot.
 
+Repo Layout
+-----------
+
+The DevStack repo generally keeps all of the primary scripts at the root
+level.
+
+``doc`` - Contains the Sphinx source for the documentation.
+``tools/build_docs.sh`` is used to generate the HTML versions of the
+DevStack scripts.  A complete doc build can be run with ``tox -edocs``.
+
+``exercises`` - Contains the test scripts used to sanity-check and
+demonstrate some OpenStack functions. These scripts know how to exit
+early or skip services that are not enabled.
+
+``extras.d`` - Contains the dispatch scripts called by the hooks in
+``stack.sh``, ``unstack.sh`` and ``clean.sh``. See :doc:`the plugins
+docs <plugins>` for more information.
+
+``files`` - Contains a variety of otherwise lost files used in
+configuring and operating DevStack. This includes templates for
+configuration files and the system dependency information. This is also
+where image files are downloaded and expanded if necessary.
+
+``lib`` - Contains the sub-scripts specific to each project. This is
+where the work of managing a project's services is located. Each
+top-level project (Keystone, Nova, etc) has a file here. Additionally
+there are some for system services and project plugins.  These
+variables and functions are also used by related projects, such as
+Grenade, to manage a DevStack installation.
+
+``samples`` - Contains a sample of the local files not included in the
+DevStack repo.
+
+``tests`` - the DevStack test suite is rather sparse, mostly consisting
+of test of specific fragile functions in the ``functions`` and
+``functions-common`` files.
+
+``tools`` - Contains a collection of stand-alone scripts. While these
+may reference the top-level DevStack configuration they can generally be
+run alone. There are also some sub-directories to support specific
+environments such as XenServer.
+
 
 Scripts
 -------
@@ -249,6 +289,7 @@
 
 Control Structure Rules
 -----------------------
+
 - then should be on the same line as the if
 - do should be on the same line as the for
 
@@ -270,6 +311,7 @@
 
 Variables and Functions
 -----------------------
+
 - functions should be used whenever possible for clarity
 - functions should use ``local`` variables as much as possible to
   ensure they are isolated from the rest of the environment
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index fe3e2c2..7d06658 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -378,6 +378,18 @@
       can be configured with any valid IPv6 prefix. The default values make
       use of an auto-generated ``IPV6_GLOBAL_ID`` to comply with RFC 4193.*
 
+Unit tests dependencies install
+-------------------------------
+
+    | *Default: ``INSTALL_TESTONLY_PACKAGES=False``*
+    |  In order to be able to run unit tests with script ``run_test.sh``,
+       the required package dependencies need to be installed.
+       Setting this option as below does the work.
+
+    ::
+
+        INSTALL_TESTONLY_PACKAGES=True
+
 Examples
 ========
 
diff --git a/doc/source/contributing.rst b/doc/source/contributing.rst
deleted file mode 100644
index 50c0100..0000000
--- a/doc/source/contributing.rst
+++ /dev/null
@@ -1,94 +0,0 @@
-============
-Contributing
-============
-
-DevStack uses the standard OpenStack contribution process as outlined in
-`the OpenStack developer
-guide <http://docs.openstack.org/infra/manual/developers.html>`__. This
-means that you will need to meet the requirements of the Contribututors
-License Agreement (CLA). If you have already done that for another
-OpenStack project you are good to go.
-
-Things To Know
-==============
-
-|
-| **Where Things Are**
-
-The official DevStack repository is located at
-``git://git.openstack.org/openstack-dev/devstack.git``, replicated from
-the repo maintained by Gerrit. GitHub also has a mirror at
-``git://github.com/openstack-dev/devstack.git``.
-
-The `blueprint <https://blueprints.launchpad.net/devstack>`__ and `bug
-trackers <https://bugs.launchpad.net/devstack>`__ are on Launchpad. It
-should be noted that DevStack generally does not use these as strongly
-as other projects, but we're trying to change that.
-
-The `Gerrit review
-queue <https://review.openstack.org/#/q/project:openstack-dev/devstack,n,z>`__
-is, however, used for all commits except for the text of this website.
-That should also change in the near future.
-
-|
-| **HACKING.rst**
-
-Like most OpenStack projects, DevStack includes a ``HACKING.rst`` file
-that describes the layout, style and conventions of the project. Because
-``HACKING.rst`` is in the main DevStack repo it is considered
-authoritative. Much of the content on this page is taken from there.
-
-|
-| **bashate Formatting**
-
-Around the time of the OpenStack Havana release we added a tool to do
-style checking in DevStack similar to what pep8/flake8 do for Python
-projects. It is still \_very\_ simplistic, focusing mostly on stray
-whitespace to help prevent -1 on reviews that are otherwise acceptable.
-Oddly enough it is called ``bashate``. It will be expanded to enforce
-some of the documentation rules in comments that are used in formatting
-the script pages for devstack.org and possibly even simple code
-formatting. Run it on the entire project with ``./run_tests.sh``.
-
-Code
-====
-
-|
-| **Repo Layout**
-
-The DevStack repo generally keeps all of the primary scripts at the root
-level.
-
-``doc`` - Contains the Sphinx source for the documentation.
-``tools/build_docs.sh`` is used to generate the HTML versions of the
-DevStack scripts.  A complete doc build can be run with ``tox -edocs``.
-
-``exercises`` - Contains the test scripts used to sanity-check and
-demonstrate some OpenStack functions. These scripts know how to exit
-early or skip services that are not enabled.
-
-``extras.d`` - Contains the dispatch scripts called by the hooks in
-``stack.sh``, ``unstack.sh`` and ``clean.sh``. See :doc:`the plugins
-docs <plugins>` for more information.
-
-``files`` - Contains a variety of otherwise lost files used in
-configuring and operating DevStack. This includes templates for
-configuration files and the system dependency information. This is also
-where image files are downloaded and expanded if necessary.
-
-``lib`` - Contains the sub-scripts specific to each project. This is
-where the work of managing a project's services is located. Each
-top-level project (Keystone, Nova, etc) has a file here. Additionally
-there are some for system services and project plugins.
-
-``samples`` - Contains a sample of the local files not included in the
-DevStack repo.
-
-``tests`` - the DevStack test suite is rather sparse, mostly consisting
-of test of specific fragile functions in the ``functions`` and
-``functions-common`` files.
-
-``tools`` - Contains a collection of stand-alone scripts. While these
-may reference the top-level DevStack configuration they can generally be
-run alone. There are also some sub-directories to support specific
-environments such as XenServer.
diff --git a/doc/source/hacking.rst b/doc/source/hacking.rst
new file mode 100644
index 0000000..a2bcf4f
--- /dev/null
+++ b/doc/source/hacking.rst
@@ -0,0 +1 @@
+.. include:: ../../HACKING.rst
diff --git a/doc/source/index.rst b/doc/source/index.rst
index bac593d..0ffb15c 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -12,7 +12,7 @@
    plugins
    faq
    changes
-   contributing
+   hacking
 
 Quick Start
 -----------
@@ -139,7 +139,7 @@
 Contributing
 ------------
 
-:doc:`Pitching in to make DevStack a better place <contributing>`
+:doc:`Pitching in to make DevStack a better place <hacking>`
 
 Code
 ====
diff --git a/doc/source/plugins.rst b/doc/source/plugins.rst
index a9763e6..5a61063 100644
--- a/doc/source/plugins.rst
+++ b/doc/source/plugins.rst
@@ -179,3 +179,24 @@
 -  ``start_nova_hypervisor`` - start any external services
 -  ``stop_nova_hypervisor`` - stop any external services
 -  ``cleanup_nova_hypervisor`` - remove transient data and cache
+
+System Packages
+===============
+
+Devstack provides a framework for getting packages installed at an early
+phase of its execution. This packages may be defined in a plugin as files
+that contain new-line separated lists of packages required by the plugin
+
+Supported packaging systems include apt and yum across multiple distributions.
+To enable a plugin to hook into this and install package dependencies, packages
+may be listed at the following locations in the top-level of the plugin
+repository:
+
+- ``./devstack/files/debs/$plugin_name`` - Packages to install when running
+  on Ubuntu, Debian or Linux Mint.
+
+- ``./devstack/files/rpms/$plugin_name`` - Packages to install when running
+  on Red Hat, Fedora, CentOS or XenServer.
+
+- ``./devstack/files/rpms-suse/$plugin_name`` - Packages to install when
+  running on SUSE Linux or openSUSE.
diff --git a/exercises/horizon.sh b/exercises/horizon.sh
deleted file mode 100755
index 4020580..0000000
--- a/exercises/horizon.sh
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env bash
-
-# **horizon.sh**
-
-# Sanity check that horizon started if enabled
-
-echo "*********************************************************************"
-echo "Begin DevStack Exercise: $0"
-echo "*********************************************************************"
-
-# This script exits on an error so that errors don't compound and you see
-# only the first error that occurred.
-set -o errexit
-
-# Print the commands being run so that we can see the command that triggers
-# an error.  It is also useful for following allowing as the install occurs.
-set -o xtrace
-
-
-# Settings
-# ========
-
-# Keep track of the current directory
-EXERCISE_DIR=$(cd $(dirname "$0") && pwd)
-TOP_DIR=$(cd $EXERCISE_DIR/..; pwd)
-
-# Import common functions
-source $TOP_DIR/functions
-
-# Import configuration
-source $TOP_DIR/openrc
-
-# Import exercise configuration
-source $TOP_DIR/exerciserc
-
-is_service_enabled horizon || exit 55
-
-# can we get the front page
-$CURL_GET http://$SERVICE_HOST 2>/dev/null | grep -q '<h3.*>Log In</h3>' || die $LINENO "Horizon front page not functioning!"
-
-set +o xtrace
-echo "*********************************************************************"
-echo "SUCCESS: End DevStack Exercise: $0"
-echo "*********************************************************************"
-
diff --git a/files/rpms/ceilometer-collector b/files/rpms/ceilometer-collector
index 9cf580d..b139ed2 100644
--- a/files/rpms/ceilometer-collector
+++ b/files/rpms/ceilometer-collector
@@ -1,4 +1,3 @@
 selinux-policy-targeted
 mongodb-server #NOPRIME
-pymongo # NOPRIME
 mongodb # NOPRIME
diff --git a/files/rpms/cinder b/files/rpms/cinder
index 082a35a..9f1359f 100644
--- a/files/rpms/cinder
+++ b/files/rpms/cinder
@@ -3,4 +3,3 @@
 qemu-img
 postgresql-devel
 iscsi-initiator-utils
-python-lxml
diff --git a/files/rpms/glance b/files/rpms/glance
index a09b669..119492a 100644
--- a/files/rpms/glance
+++ b/files/rpms/glance
@@ -3,12 +3,4 @@
 mysql-devel         # testonly
 openssl-devel       # testonly
 postgresql-devel    # testonly
-python-argparse
-python-eventlet
-python-greenlet
-python-lxml
-python-paste-deploy
-python-routes
-python-sqlalchemy
-pyxattr
 zlib-devel          # testonly
diff --git a/files/rpms/horizon b/files/rpms/horizon
index 585c36c..8d7f037 100644
--- a/files/rpms/horizon
+++ b/files/rpms/horizon
@@ -2,20 +2,5 @@
 httpd # NOPRIME
 mod_wsgi  # NOPRIME
 pylint
-python-anyjson
-python-BeautifulSoup
-python-coverage
-python-dateutil
-python-eventlet
-python-greenlet
-python-httplib2
-python-migrate
-python-mox
-python-nose
-python-paste
-python-paste-deploy
-python-routes
-python-sqlalchemy
-python-webob
 pyxattr
 pcre-devel  # pyScss
diff --git a/files/rpms/ironic b/files/rpms/ironic
index 0a46314..2bf8bb3 100644
--- a/files/rpms/ironic
+++ b/files/rpms/ironic
@@ -8,7 +8,6 @@
 net-tools
 openssh-clients
 openvswitch
-python-libguestfs
 sgabios
 syslinux
 tftp-server
diff --git a/files/rpms/keystone b/files/rpms/keystone
index 45492e0..8074119 100644
--- a/files/rpms/keystone
+++ b/files/rpms/keystone
@@ -1,14 +1,4 @@
 MySQL-python
-python-greenlet
 libxslt-devel
-python-lxml
-python-paste
-python-paste-deploy
-python-paste-script
-python-routes
-python-sqlalchemy
-python-webob
 sqlite
 mod_ssl
-
-# Deps installed via pip for RHEL
diff --git a/files/rpms/ldap b/files/rpms/ldap
index 2f7ab5d..d89c4cf 100644
--- a/files/rpms/ldap
+++ b/files/rpms/ldap
@@ -1,3 +1,2 @@
 openldap-servers
 openldap-clients
-python-ldap
diff --git a/files/rpms/n-api b/files/rpms/n-api
index 6f59e60..0928cd5 100644
--- a/files/rpms/n-api
+++ b/files/rpms/n-api
@@ -1,2 +1 @@
-python-dateutil
 fping
diff --git a/files/rpms/n-cpu b/files/rpms/n-cpu
index 32b1546..c1a8e8f 100644
--- a/files/rpms/n-cpu
+++ b/files/rpms/n-cpu
@@ -4,4 +4,4 @@
 genisoimage
 sysfsutils
 sg3_utils
-python-libguestfs # NOPRIME
+
diff --git a/files/rpms/neutron b/files/rpms/neutron
index d11dab7..c0dee78 100644
--- a/files/rpms/neutron
+++ b/files/rpms/neutron
@@ -10,15 +10,6 @@
 mysql-server # NOPRIME
 openvswitch # NOPRIME
 postgresql-devel        # testonly
-python-eventlet
-python-greenlet
-python-iso8601
-python-paste
-python-paste-deploy
-python-qpid # NOPRIME
-python-routes
-python-sqlalchemy
-python-suds
 rabbitmq-server # NOPRIME
 qpid-cpp-server        # NOPRIME
 sqlite
diff --git a/files/rpms/nova b/files/rpms/nova
index 557de90..527928a 100644
--- a/files/rpms/nova
+++ b/files/rpms/nova
@@ -21,22 +21,6 @@
 mysql-server # NOPRIME
 parted
 polkit
-python-cheetah
-python-eventlet
-python-feedparser
-python-greenlet
-python-iso8601
-python-lockfile
-python-migrate
-python-mox
-python-paramiko
-python-paste
-python-paste-deploy
-python-qpid # NOPRIME
-python-routes
-python-sqlalchemy
-python-suds
-python-tempita
 rabbitmq-server # NOPRIME
 qpid-cpp-server # NOPRIME
 sqlite
diff --git a/files/rpms/qpid b/files/rpms/qpid
index c5e2699..41dd2f6 100644
--- a/files/rpms/qpid
+++ b/files/rpms/qpid
@@ -1,4 +1,3 @@
 qpid-proton-c-devel # NOPRIME
-python-qpid-proton # NOPRIME
 cyrus-sasl-lib # NOPRIME
 cyrus-sasl-plain # NOPRIME
diff --git a/files/rpms/swift b/files/rpms/swift
index 0fcdb0f..1bf57cc 100644
--- a/files/rpms/swift
+++ b/files/rpms/swift
@@ -1,15 +1,7 @@
 curl
 memcached
-python-configobj
-python-coverage
-python-eventlet
-python-greenlet
-python-netifaces
-python-nose
-python-paste-deploy
-python-simplejson
-python-webob
 pyxattr
 sqlite
 xfsprogs
 xinetd
+rsync-daemon # dist:f22,f23
diff --git a/files/rpms/zaqar-server b/files/rpms/zaqar-server
index 541cefa..78806fb 100644
--- a/files/rpms/zaqar-server
+++ b/files/rpms/zaqar-server
@@ -3,4 +3,3 @@
 mongodb-server
 pymongo
 redis # NOPRIME
-python-redis # NOPRIME
diff --git a/functions-common b/functions-common
index 4739e42..b94e134 100644
--- a/functions-common
+++ b/functions-common
@@ -542,11 +542,11 @@
     local host_ip_iface=$3
     local host_ip=$4
 
-    # Find the interface used for the default route
-    host_ip_iface=${host_ip_iface:-$(ip route | sed -n '/^default/{ s/.*dev \(\w\+\)\s\+.*/\1/; p; }' | head -1)}
     # Search for an IP unless an explicit is set by ``HOST_IP`` environment variable
     if [ -z "$host_ip" -o "$host_ip" == "dhcp" ]; then
         host_ip=""
+        # Find the interface used for the default route
+        host_ip_iface=${host_ip_iface:-$(ip route | awk '/default/ {print $5}' | head -1)}
         local host_ips=$(LC_ALL=C ip -f inet addr show ${host_ip_iface} | awk '/inet/ {split($2,parts,"/");  print parts[1]}')
         local ip
         for ip in $host_ips; do
@@ -588,6 +588,28 @@
     done
 }
 
+# install default policy
+# copy over a default policy.json and policy.d for projects
+function install_default_policy {
+    local project=$1
+    local project_uc=$(echo $1|tr a-z A-Z)
+    local conf_dir="${project_uc}_CONF_DIR"
+    # eval conf dir to get the variable
+    conf_dir="${!conf_dir}"
+    local project_dir="${project_uc}_DIR"
+    # eval project dir to get the variable
+    project_dir="${!project_dir}"
+    local sample_conf_dir="${project_dir}/etc/${project}"
+    local sample_policy_dir="${project_dir}/etc/${project}/policy.d"
+
+    # first copy any policy.json
+    cp -p $sample_conf_dir/policy.json $conf_dir
+    # then optionally copy over policy.d
+    if [[ -d $sample_policy_dir ]]; then
+        cp -r $sample_policy_dir $conf_dir/policy.d
+    fi
+}
+
 # Add a policy to a policy.json file
 # Do nothing if the policy already exists
 # ``policy_add policy_file policy_name policy_permissions``
@@ -774,13 +796,18 @@
 
 # _get_package_dir
 function _get_package_dir {
+    local base_dir=$1
     local pkg_dir
+
+    if [[ -z "$base_dir" ]]; then
+        base_dir=$FILES
+    fi
     if is_ubuntu; then
-        pkg_dir=$FILES/debs
+        pkg_dir=$base_dir/debs
     elif is_fedora; then
-        pkg_dir=$FILES/rpms
+        pkg_dir=$base_dir/rpms
     elif is_suse; then
-        pkg_dir=$FILES/rpms-suse
+        pkg_dir=$base_dir/rpms-suse
     else
         exit_distro_not_supported "list of packages"
     fi
@@ -806,84 +833,14 @@
         apt-get --option "Dpkg::Options::=--force-confold" --assume-yes "$@"
 }
 
-# get_packages() collects a list of package names of any type from the
-# prerequisite files in ``files/{debs|rpms}``.  The list is intended
-# to be passed to a package installer such as apt or yum.
-#
-# Only packages required for the services in 1st argument will be
-# included.  Two bits of metadata are recognized in the prerequisite files:
-#
-# - ``# NOPRIME`` defers installation to be performed later in `stack.sh`
-# - ``# dist:DISTRO`` or ``dist:DISTRO1,DISTRO2`` limits the selection
-#   of the package to the distros listed.  The distro names are case insensitive.
-function get_packages {
-    local xtrace=$(set +o | grep xtrace)
-    set +o xtrace
-    local services=$@
-    local package_dir=$(_get_package_dir)
-    local file_to_parse=""
-    local service=""
+function _parse_package_files {
+    local files_to_parse=$@
 
-    INSTALL_TESTONLY_PACKAGES=$(trueorfalse False INSTALL_TESTONLY_PACKAGES)
-
-    if [[ -z "$package_dir" ]]; then
-        echo "No package directory supplied"
-        return 1
-    fi
     if [[ -z "$DISTRO" ]]; then
         GetDistro
     fi
-    for service in ${services//,/ }; do
-        # Allow individual services to specify dependencies
-        if [[ -e ${package_dir}/${service} ]]; then
-            file_to_parse="${file_to_parse} $service"
-        fi
-        # NOTE(sdague) n-api needs glance for now because that's where
-        # glance client is
-        if [[ $service == n-api ]]; then
-            if [[ ! $file_to_parse =~ nova ]]; then
-                file_to_parse="${file_to_parse} nova"
-            fi
-            if [[ ! $file_to_parse =~ glance ]]; then
-                file_to_parse="${file_to_parse} glance"
-            fi
-        elif [[ $service == c-* ]]; then
-            if [[ ! $file_to_parse =~ cinder ]]; then
-                file_to_parse="${file_to_parse} cinder"
-            fi
-        elif [[ $service == ceilometer-* ]]; then
-            if [[ ! $file_to_parse =~ ceilometer ]]; then
-                file_to_parse="${file_to_parse} ceilometer"
-            fi
-        elif [[ $service == s-* ]]; then
-            if [[ ! $file_to_parse =~ swift ]]; then
-                file_to_parse="${file_to_parse} swift"
-            fi
-        elif [[ $service == n-* ]]; then
-            if [[ ! $file_to_parse =~ nova ]]; then
-                file_to_parse="${file_to_parse} nova"
-            fi
-        elif [[ $service == g-* ]]; then
-            if [[ ! $file_to_parse =~ glance ]]; then
-                file_to_parse="${file_to_parse} glance"
-            fi
-        elif [[ $service == key* ]]; then
-            if [[ ! $file_to_parse =~ keystone ]]; then
-                file_to_parse="${file_to_parse} keystone"
-            fi
-        elif [[ $service == q-* ]]; then
-            if [[ ! $file_to_parse =~ neutron ]]; then
-                file_to_parse="${file_to_parse} neutron"
-            fi
-        elif [[ $service == ir-* ]]; then
-            if [[ ! $file_to_parse =~ ironic ]]; then
-                file_to_parse="${file_to_parse} ironic"
-            fi
-        fi
-    done
 
-    for file in ${file_to_parse}; do
-        local fname=${package_dir}/${file}
+    for fname in ${files_to_parse}; do
         local OIFS line package distros distro
         [[ -e $fname ]] || continue
 
@@ -927,6 +884,102 @@
         done
         IFS=$OIFS
     done
+}
+
+# get_packages() collects a list of package names of any type from the
+# prerequisite files in ``files/{debs|rpms}``.  The list is intended
+# to be passed to a package installer such as apt or yum.
+#
+# Only packages required for the services in 1st argument will be
+# included.  Two bits of metadata are recognized in the prerequisite files:
+#
+# - ``# NOPRIME`` defers installation to be performed later in `stack.sh`
+# - ``# dist:DISTRO`` or ``dist:DISTRO1,DISTRO2`` limits the selection
+#   of the package to the distros listed.  The distro names are case insensitive.
+function get_packages {
+    local xtrace=$(set +o | grep xtrace)
+    set +o xtrace
+    local services=$@
+    local package_dir=$(_get_package_dir)
+    local file_to_parse=""
+    local service=""
+
+    INSTALL_TESTONLY_PACKAGES=$(trueorfalse False INSTALL_TESTONLY_PACKAGES)
+
+    if [[ -z "$package_dir" ]]; then
+        echo "No package directory supplied"
+        return 1
+    fi
+    for service in ${services//,/ }; do
+        # Allow individual services to specify dependencies
+        if [[ -e ${package_dir}/${service} ]]; then
+            file_to_parse="${file_to_parse} ${package_dir}/${service}"
+        fi
+        # NOTE(sdague) n-api needs glance for now because that's where
+        # glance client is
+        if [[ $service == n-api ]]; then
+            if [[ ! $file_to_parse =~ $package_dir/nova ]]; then
+                file_to_parse="${file_to_parse} ${package_dir}/nova"
+            fi
+            if [[ ! $file_to_parse =~ $package_dir/glance ]]; then
+                file_to_parse="${file_to_parse} ${package_dir}/glance"
+            fi
+        elif [[ $service == c-* ]]; then
+            if [[ ! $file_to_parse =~ $package_dir/cinder ]]; then
+                file_to_parse="${file_to_parse} ${package_dir}/cinder"
+            fi
+        elif [[ $service == ceilometer-* ]]; then
+            if [[ ! $file_to_parse =~ $package_dir/ceilometer ]]; then
+                file_to_parse="${file_to_parse} ${package_dir}/ceilometer"
+            fi
+        elif [[ $service == s-* ]]; then
+            if [[ ! $file_to_parse =~ $package_dir/swift ]]; then
+                file_to_parse="${file_to_parse} ${package_dir}/swift"
+            fi
+        elif [[ $service == n-* ]]; then
+            if [[ ! $file_to_parse =~ $package_dir/nova ]]; then
+                file_to_parse="${file_to_parse} ${package_dir}/nova"
+            fi
+        elif [[ $service == g-* ]]; then
+            if [[ ! $file_to_parse =~ $package_dir/glance ]]; then
+                file_to_parse="${file_to_parse} ${package_dir}/glance"
+            fi
+        elif [[ $service == key* ]]; then
+            if [[ ! $file_to_parse =~ $package_dir/keystone ]]; then
+                file_to_parse="${file_to_parse} ${package_dir}/keystone"
+            fi
+        elif [[ $service == q-* ]]; then
+            if [[ ! $file_to_parse =~ $package_dir/neutron ]]; then
+                file_to_parse="${file_to_parse} ${package_dir}/neutron"
+            fi
+        elif [[ $service == ir-* ]]; then
+            if [[ ! $file_to_parse =~ $package_dir/ironic ]]; then
+                file_to_parse="${file_to_parse} ${package_dir}/ironic"
+            fi
+        fi
+    done
+    echo "$(_parse_package_files $file_to_parse)"
+    $xtrace
+}
+
+# get_plugin_packages() collects a list of package names of any type from a
+# plugin's prerequisite files in ``$PLUGIN/devstack/files/{debs|rpms}``.  The
+# list is intended to be passed to a package installer such as apt or yum.
+#
+# Only packages required for enabled and collected plugins will included.
+#
+# The same metadata used in the main devstack prerequisite files may be used
+# in these prerequisite files, see get_packages() for more info.
+function get_plugin_packages {
+    local xtrace=$(set +o | grep xtrace)
+    set +o xtrace
+    local files_to_parse=""
+    local package_dir=""
+    for plugin in ${DEVSTACK_PLUGINS//,/ }; do
+        local package_dir="$(_get_package_dir ${GITDIR[$plugin]}/devstack/files)"
+        files_to_parse+="$package_dir/$plugin"
+    done
+    echo "$(_parse_package_files $files_to_parse)"
     $xtrace
 }
 
@@ -1019,8 +1072,8 @@
     # The manual check for missing packages is because yum -y assumes
     # missing packages are OK.  See
     # https://bugzilla.redhat.com/show_bug.cgi?id=965567
-    $sudo http_proxy=$http_proxy https_proxy=$https_proxy \
-        no_proxy=$no_proxy \
+    $sudo http_proxy="${http_proxy:-}" https_proxy="${https_proxy:-}" \
+        no_proxy="${no_proxy:-}" \
         ${YUM:-yum} install -y "$@" 2>&1 | \
         awk '
             BEGIN { fail=0 }
@@ -1042,7 +1095,8 @@
     [[ "$OFFLINE" = "True" ]] && return
     local sudo="sudo"
     [[ "$(id -u)" = "0" ]] && sudo="env"
-    $sudo http_proxy=$http_proxy https_proxy=$https_proxy \
+    $sudo http_proxy="${http_proxy:-}" https_proxy="${https_proxy:-}" \
+        no_proxy="${no_proxy:-}" \
         zypper --non-interactive install --auto-agree-with-licenses "$@"
 }
 
diff --git a/inc/python b/inc/python
index d72c3c9..229c540 100644
--- a/inc/python
+++ b/inc/python
@@ -94,9 +94,9 @@
 
     $xtrace
     $sudo_pip \
-        http_proxy=${http_proxy:-} \
-        https_proxy=${https_proxy:-} \
-        no_proxy=${no_proxy:-} \
+        http_proxy="${http_proxy:-}" \
+        https_proxy="${https_proxy:-}" \
+        no_proxy="${no_proxy:-}" \
         PIP_FIND_LINKS=$PIP_FIND_LINKS \
         $cmd_pip install \
         $@
diff --git a/lib/ceilometer b/lib/ceilometer
index e240083..7b2215c 100644
--- a/lib/ceilometer
+++ b/lib/ceilometer
@@ -163,11 +163,7 @@
 
 # configure_ceilometer() - Set config files, create data dirs, etc
 function configure_ceilometer {
-    [ ! -d $CEILOMETER_CONF_DIR ] && sudo mkdir -m 755 -p $CEILOMETER_CONF_DIR
-    sudo chown $STACK_USER $CEILOMETER_CONF_DIR
-
-    [ ! -d $CEILOMETER_API_LOG_DIR ] &&  sudo mkdir -m 755 -p $CEILOMETER_API_LOG_DIR
-    sudo chown $STACK_USER $CEILOMETER_API_LOG_DIR
+    sudo install -d -o $STACK_USER -m 755 $CEILOMETER_CONF_DIR $CEILOMETER_API_LOG_DIR
 
     iniset_rpc_backend ceilometer $CEILOMETER_CONF
 
@@ -267,8 +263,7 @@
 # init_ceilometer() - Initialize etc.
 function init_ceilometer {
     # Create cache dir
-    sudo mkdir -p $CEILOMETER_AUTH_CACHE_DIR
-    sudo chown $STACK_USER $CEILOMETER_AUTH_CACHE_DIR
+    sudo install -d -o $STACK_USER $CEILOMETER_AUTH_CACHE_DIR
     rm -f $CEILOMETER_AUTH_CACHE_DIR/*
 
     if is_service_enabled mysql postgresql; then
@@ -322,6 +317,8 @@
     if use_library_from_git "ceilometermiddleware"; then
         git_clone_by_name "ceilometermiddleware"
         setup_dev_lib "ceilometermiddleware"
+    else
+        pip_install ceilometermiddleware
     fi
 }
 
diff --git a/lib/cinder b/lib/cinder
index a8f0538..ef68d8d 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -174,16 +174,15 @@
     if [[ -d $CINDER_CONF_DIR/rootwrap.d ]]; then
         sudo rm -rf $CINDER_CONF_DIR/rootwrap.d
     fi
+
     # Deploy filters to /etc/cinder/rootwrap.d
-    sudo mkdir -m 755 $CINDER_CONF_DIR/rootwrap.d
-    sudo cp $CINDER_DIR/etc/cinder/rootwrap.d/*.filters $CINDER_CONF_DIR/rootwrap.d
-    sudo chown -R root:root $CINDER_CONF_DIR/rootwrap.d
-    sudo chmod 644 $CINDER_CONF_DIR/rootwrap.d/*
+    sudo install -d -o root -g root -m 755 $CINDER_CONF_DIR/rootwrap.d
+    sudo install -o root -g root -m 644 $CINDER_DIR/etc/cinder/rootwrap.d/*.filters $CINDER_CONF_DIR/rootwrap.d
+
     # Set up rootwrap.conf, pointing to /etc/cinder/rootwrap.d
-    sudo cp $CINDER_DIR/etc/cinder/rootwrap.conf $CINDER_CONF_DIR/
+    sudo install -o root -g root -m 644 $CINDER_DIR/etc/cinder/rootwrap.conf $CINDER_CONF_DIR
     sudo sed -e "s:^filters_path=.*$:filters_path=$CINDER_CONF_DIR/rootwrap.d:" -i $CINDER_CONF_DIR/rootwrap.conf
-    sudo chown root:root $CINDER_CONF_DIR/rootwrap.conf
-    sudo chmod 0644 $CINDER_CONF_DIR/rootwrap.conf
+
     # Specify rootwrap.conf as first parameter to rootwrap
     ROOTWRAP_CSUDOER_CMD="$cinder_rootwrap $CINDER_CONF_DIR/rootwrap.conf *"
 
@@ -197,10 +196,7 @@
 
 # configure_cinder() - Set config files, create data dirs, etc
 function configure_cinder {
-    if [[ ! -d $CINDER_CONF_DIR ]]; then
-        sudo mkdir -p $CINDER_CONF_DIR
-    fi
-    sudo chown $STACK_USER $CINDER_CONF_DIR
+    sudo install -d -o $STACK_USER -m 755 $CINDER_CONF_DIR
 
     cp -p $CINDER_DIR/etc/cinder/policy.json $CINDER_CONF_DIR
 
@@ -229,12 +225,12 @@
     iniset $CINDER_CONF DEFAULT verbose True
 
     iniset $CINDER_CONF DEFAULT iscsi_helper tgtadm
-    iniset $CINDER_CONF DEFAULT sql_connection `database_connection_url cinder`
+    iniset $CINDER_CONF database connection `database_connection_url cinder`
     iniset $CINDER_CONF DEFAULT api_paste_config $CINDER_API_PASTE_INI
     iniset $CINDER_CONF DEFAULT rootwrap_config "$CINDER_CONF_DIR/rootwrap.conf"
     iniset $CINDER_CONF DEFAULT osapi_volume_extension cinder.api.contrib.standard_extensions
     iniset $CINDER_CONF DEFAULT state_path $CINDER_STATE_PATH
-    iniset $CINDER_CONF DEFAULT lock_path $CINDER_STATE_PATH
+    iniset $CINDER_CONF oslo_concurrency lock_path $CINDER_STATE_PATH
     iniset $CINDER_CONF DEFAULT periodic_interval $CINDER_PERIODIC_INTERVAL
     # NOTE(thingee): Cinder V1 API is deprecated and defaults to off as of
     # Juno. Keep it enabled so we can continue testing while it's still
@@ -351,8 +347,7 @@
 # create_cinder_cache_dir() - Part of the init_cinder() process
 function create_cinder_cache_dir {
     # Create cache dir
-    sudo mkdir -p $CINDER_AUTH_CACHE_DIR
-    sudo chown $STACK_USER $CINDER_AUTH_CACHE_DIR
+    sudo install -d -o $STACK_USER $CINDER_AUTH_CACHE_DIR
     rm -f $CINDER_AUTH_CACHE_DIR/*
 }
 
@@ -372,15 +367,9 @@
 
     if is_service_enabled c-vol && [[ -n "$CINDER_ENABLED_BACKENDS" ]]; then
         local be be_name be_type
-        local has_lvm=0
         for be in ${CINDER_ENABLED_BACKENDS//,/ }; do
             be_type=${be%%:*}
             be_name=${be##*:}
-
-            if [[ $be_type == 'lvm' ]]; then
-                has_lvm=1
-            fi
-
             if type init_cinder_backend_${be_type} >/dev/null 2>&1; then
                 # Always init the default volume group for lvm.
                 if [[ "$be_type" == "lvm" ]]; then
@@ -391,17 +380,6 @@
         done
     fi
 
-    # Keep it simple, set a marker if there's an LVM backend
-    # use the created VG's to setup lvm filters
-    if [[ $has_lvm == 1 ]]; then
-        # Order matters here, not only obviously to make
-        # sure the VG's are created, but also some distros
-        # do some customizations to lvm.conf on init, we
-        # want to make sure we copy those over
-        sudo cp /etc/lvm/lvm.conf /etc/cinder/lvm.conf
-        configure_cinder_backend_conf_lvm
-    fi
-
     mkdir -p $CINDER_STATE_PATH/volumes
     create_cinder_cache_dir
 }
diff --git a/lib/cinder_backends/lvm b/lib/cinder_backends/lvm
index 52fc6fb..f210578 100644
--- a/lib/cinder_backends/lvm
+++ b/lib/cinder_backends/lvm
@@ -19,7 +19,6 @@
 # clean_cinder_backend_lvm - called from clean_cinder()
 # configure_cinder_backend_lvm - called from configure_cinder()
 # init_cinder_backend_lvm - called from init_cinder()
-# configure_cinder_backend_conf_lvm - called from configure_cinder()
 
 
 # Save trace setting
@@ -66,36 +65,6 @@
     init_lvm_volume_group $VOLUME_GROUP_NAME-$be_name $VOLUME_BACKING_FILE_SIZE
 }
 
-# configure_cinder_backend_conf_lvm - Sets device filter in /etc/cinder/lvm.conf
-# init_cinder_backend_lvm
-function configure_cinder_backend_conf_lvm {
-    local filter_suffix='"r/.*/" ]'
-    local filter_string="filter = [ "
-    local conf_entries=$(grep volume_group /etc/cinder/cinder.conf | sed "s/ //g")
-    local pv
-    local vg
-    local line
-
-    for pv_info in $(sudo pvs --noheadings -o name,vg_name --separator ';'); do
-        echo_summary "Evaluate PV info for Cinder lvm.conf: $pv_info"
-        IFS=';' read pv vg <<< "$pv_info"
-        for line in ${conf_entries}; do
-            IFS='=' read label group <<< "$line"
-            group=$(echo $group|sed "s/^ *//g")
-            if [[ "$vg" == "$group" ]]; then
-                new="\"a$pv/\", "
-                filter_string=$filter_string$new
-            fi
-        done
-    done
-    filter_string=$filter_string$filter_suffix
-
-    # FIXME(jdg): Possible odd case that the lvm.conf file has been modified
-    # and doesn't have a filter entry to search/replace.  For devstack don't
-    # know that we care, but could consider adding a check and add
-    sudo sed -i "s#^[ \t]*filter.*#    $filter_string#g" /etc/cinder/lvm.conf
-    echo "set LVM filter_strings: $filter_string"
-}
 # Restore xtrace
 $MY_XTRACE
 
diff --git a/lib/glance b/lib/glance
index 8400ca1..d781056 100755
--- a/lib/glance
+++ b/lib/glance
@@ -90,15 +90,7 @@
 
 # configure_glance() - Set config files, create data dirs, etc
 function configure_glance {
-    if [[ ! -d $GLANCE_CONF_DIR ]]; then
-        sudo mkdir -p $GLANCE_CONF_DIR
-    fi
-    sudo chown $STACK_USER $GLANCE_CONF_DIR
-
-    if [[ ! -d $GLANCE_METADEF_DIR ]]; then
-        sudo mkdir -p $GLANCE_METADEF_DIR
-    fi
-    sudo chown $STACK_USER $GLANCE_METADEF_DIR
+    sudo install -d -o $STACK_USER $GLANCE_CONF_DIR $GLANCE_METADEF_DIR
 
     # Copy over our glance configurations and update them
     cp $GLANCE_DIR/etc/glance-registry.conf $GLANCE_REGISTRY_CONF
@@ -185,8 +177,8 @@
 
     # Format logging
     if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
-        setup_colorized_logging $GLANCE_API_CONF DEFAULT "project_id" "user_id"
-        setup_colorized_logging $GLANCE_REGISTRY_CONF DEFAULT "project_id" "user_id"
+        setup_colorized_logging $GLANCE_API_CONF DEFAULT tenant user
+        setup_colorized_logging $GLANCE_REGISTRY_CONF DEFAULT tenant user
     fi
 
     cp -p $GLANCE_DIR/etc/glance-registry-paste.ini $GLANCE_REGISTRY_PASTE_INI
@@ -263,12 +255,8 @@
 # create_glance_cache_dir() - Part of the init_glance() process
 function create_glance_cache_dir {
     # Create cache dir
-    sudo mkdir -p $GLANCE_AUTH_CACHE_DIR/api
-    sudo chown $STACK_USER $GLANCE_AUTH_CACHE_DIR/api
-    rm -f $GLANCE_AUTH_CACHE_DIR/api/*
-    sudo mkdir -p $GLANCE_AUTH_CACHE_DIR/registry
-    sudo chown $STACK_USER $GLANCE_AUTH_CACHE_DIR/registry
-    rm -f $GLANCE_AUTH_CACHE_DIR/registry/*
+    sudo install -d -o $STACK_USER $GLANCE_AUTH_CACHE_DIR/api $GLANCE_AUTH_CACHE_DIR/registry
+    rm -f $GLANCE_AUTH_CACHE_DIR/api/* $GLANCE_AUTH_CACHE_DIR/registry/*
 }
 
 # init_glance() - Initialize databases, etc.
diff --git a/lib/heat b/lib/heat
index d713f18..f69e803 100644
--- a/lib/heat
+++ b/lib/heat
@@ -49,13 +49,19 @@
 HEAT_CONF=$HEAT_CONF_DIR/heat.conf
 HEAT_ENV_DIR=$HEAT_CONF_DIR/environment.d
 HEAT_TEMPLATES_DIR=$HEAT_CONF_DIR/templates
-HEAT_STACK_DOMAIN=$(trueorfalse True HEAT_STACK_DOMAIN)
 HEAT_API_HOST=${HEAT_API_HOST:-$HOST_IP}
 HEAT_API_PORT=${HEAT_API_PORT:-8004}
 
 
 # other default options
-HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-trusts}
+if [[ "$HEAT_STANDALONE" = "True" ]]; then
+    # for standalone, use defaults which require no service user
+    HEAT_STACK_DOMAIN=`trueorfalse False $HEAT_STACK_DOMAIN`
+    HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-password}
+else
+    HEAT_STACK_DOMAIN=`trueorfalse True $HEAT_STACK_DOMAIN`
+    HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-trusts}
+fi
 
 # Tell Tempest this project is present
 TEMPEST_SERVICES+=,heat
@@ -77,18 +83,13 @@
     sudo rm -rf $HEAT_AUTH_CACHE_DIR
     sudo rm -rf $HEAT_ENV_DIR
     sudo rm -rf $HEAT_TEMPLATES_DIR
+    sudo rm -rf $HEAT_CONF_DIR
 }
 
 # configure_heat() - Set config files, create data dirs, etc
 function configure_heat {
-    if [[ "$HEAT_STANDALONE" = "True" ]]; then
-        setup_develop $HEAT_DIR/contrib/heat_keystoneclient_v2
-    fi
 
-    if [[ ! -d $HEAT_CONF_DIR ]]; then
-        sudo mkdir -p $HEAT_CONF_DIR
-    fi
-    sudo chown $STACK_USER $HEAT_CONF_DIR
+    sudo install -d -o $STACK_USER $HEAT_CONF_DIR
     # remove old config files
     rm -f $HEAT_CONF_DIR/heat-*.conf
 
@@ -127,24 +128,22 @@
     # auth plugin setup. This should be fixed in heat.  Heat is also the only
     # service that requires the auth_uri to include a /v2.0. Remove this custom
     # setup when bug #1300246 is resolved.
-    iniset $HEAT_CONF keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
     iniset $HEAT_CONF keystone_authtoken auth_uri $KEYSTONE_SERVICE_URI/v2.0
-    iniset $HEAT_CONF keystone_authtoken admin_user heat
-    iniset $HEAT_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
-    iniset $HEAT_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset $HEAT_CONF keystone_authtoken cafile $SSL_BUNDLE_FILE
-    iniset $HEAT_CONF keystone_authtoken signing_dir $HEAT_AUTH_CACHE_DIR
+    if [[ "$HEAT_STANDALONE" = "True" ]]; then
+        iniset $HEAT_CONF paste_deploy flavor standalone
+        iniset $HEAT_CONF clients_heat url "http://$HEAT_API_HOST:$HEAT_API_PORT/v1/%(tenant_id)s"
+    else
+        iniset $HEAT_CONF keystone_authtoken identity_uri $KEYSTONE_AUTH_URI
+        iniset $HEAT_CONF keystone_authtoken admin_user heat
+        iniset $HEAT_CONF keystone_authtoken admin_password $SERVICE_PASSWORD
+        iniset $HEAT_CONF keystone_authtoken admin_tenant_name $SERVICE_TENANT_NAME
+        iniset $HEAT_CONF keystone_authtoken cafile $SSL_BUNDLE_FILE
+        iniset $HEAT_CONF keystone_authtoken signing_dir $HEAT_AUTH_CACHE_DIR
+    fi
 
     # ec2authtoken
     iniset $HEAT_CONF ec2authtoken auth_uri $KEYSTONE_SERVICE_URI/v2.0
 
-    # paste_deploy
-    if [[ "$HEAT_STANDALONE" = "True" ]]; then
-        iniset $HEAT_CONF paste_deploy flavor standalone
-        iniset $HEAT_CONF DEFAULT keystone_backend heat_keystoneclient_v2.client.KeystoneClientV2
-        iniset $HEAT_CONF clients_heat url "http://$HEAT_API_HOST:$HEAT_API_PORT/v1/%(tenant_id)s"
-    fi
-
     # OpenStack API
     iniset $HEAT_CONF heat_api bind_port $HEAT_API_PORT
     iniset $HEAT_CONF heat_api workers "$API_WORKERS"
@@ -172,15 +171,11 @@
         iniset $HEAT_CONF DEFAULT enable_stack_abandon true
     fi
 
-    # heat environment
-    sudo mkdir -p $HEAT_ENV_DIR
-    sudo chown $STACK_USER $HEAT_ENV_DIR
+    sudo install -d -o $STACK_USER $HEAT_ENV_DIR $HEAT_TEMPLATES_DIR
+
     # copy the default environment
     cp $HEAT_DIR/etc/heat/environment.d/* $HEAT_ENV_DIR/
 
-    # heat template resources.
-    sudo mkdir -p $HEAT_TEMPLATES_DIR
-    sudo chown $STACK_USER $HEAT_TEMPLATES_DIR
     # copy the default templates
     cp $HEAT_DIR/etc/heat/templates/* $HEAT_TEMPLATES_DIR/
 
@@ -199,8 +194,7 @@
 # create_heat_cache_dir() - Part of the init_heat() process
 function create_heat_cache_dir {
     # Create cache dirs
-    sudo mkdir -p $HEAT_AUTH_CACHE_DIR
-    sudo chown $STACK_USER $HEAT_AUTH_CACHE_DIR
+    sudo install -d -o $STACK_USER $HEAT_AUTH_CACHE_DIR
 }
 
 # install_heatclient() - Collect source and prepare
@@ -243,30 +237,33 @@
 
 # create_heat_accounts() - Set up common required heat accounts
 function create_heat_accounts {
-    create_service_user "heat" "admin"
+    if [[ "$HEAT_STANDALONE" != "True" ]]; then
 
-    if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
+        create_service_user "heat" "admin"
 
-        local heat_service=$(get_or_create_service "heat" \
-                "orchestration" "Heat Orchestration Service")
-        get_or_create_endpoint $heat_service \
-            "$REGION_NAME" \
-            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
-            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
-            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s"
+        if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
 
-        local heat_cfn_service=$(get_or_create_service "heat-cfn" \
-                "cloudformation" "Heat CloudFormation Service")
-        get_or_create_endpoint $heat_cfn_service \
-            "$REGION_NAME" \
-            "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
-            "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
-            "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1"
+            local heat_service=$(get_or_create_service "heat" \
+                    "orchestration" "Heat Orchestration Service")
+            get_or_create_endpoint $heat_service \
+                "$REGION_NAME" \
+                "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
+                "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s" \
+                "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(tenant_id)s"
+
+            local heat_cfn_service=$(get_or_create_service "heat-cfn" \
+                    "cloudformation" "Heat CloudFormation Service")
+            get_or_create_endpoint $heat_cfn_service \
+                "$REGION_NAME" \
+                "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
+                "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1" \
+                "$SERVICE_PROTOCOL://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1"
+        fi
+
+        # heat_stack_user role is for users created by Heat
+        get_or_create_role "heat_stack_user"
     fi
 
-    # heat_stack_user role is for users created by Heat
-    get_or_create_role "heat_stack_user"
-
     if [[ $HEAT_DEFERRED_AUTH == trusts ]]; then
         iniset $HEAT_CONF DEFAULT deferred_auth_method trusts
     fi
diff --git a/lib/ironic b/lib/ironic
index 2dc95bb..58cc2fa 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -63,6 +63,7 @@
 IRONIC_BAREMETAL_BASIC_OPS=$(trueorfalse False IRONIC_BAREMETAL_BASIC_OPS)
 IRONIC_ENABLED_DRIVERS=${IRONIC_ENABLED_DRIVERS:-fake,pxe_ssh,pxe_ipmitool}
 IRONIC_SSH_USERNAME=${IRONIC_SSH_USERNAME:-`whoami`}
+IRONIC_SSH_TIMEOUT=${IRONIC_SSH_TIMEOUT:-15}
 IRONIC_SSH_KEY_DIR=${IRONIC_SSH_KEY_DIR:-$IRONIC_DATA_DIR/ssh_keys}
 IRONIC_SSH_KEY_FILENAME=${IRONIC_SSH_KEY_FILENAME:-ironic_key}
 IRONIC_KEY_FILE=${IRONIC_KEY_FILE:-$IRONIC_SSH_KEY_DIR/$IRONIC_SSH_KEY_FILENAME}
@@ -233,22 +234,14 @@
 # configure_ironic_dirs() - Create all directories required by Ironic and
 # associated services.
 function configure_ironic_dirs {
-    if [[ ! -d $IRONIC_CONF_DIR ]]; then
-        sudo mkdir -p $IRONIC_CONF_DIR
-    fi
+    sudo install -d -o $STACK_USER $IRONIC_CONF_DIR $STACK_USER $IRONIC_DATA_DIR \
+        $IRONIC_STATE_PATH $IRONIC_TFTPBOOT_DIR $IRONIC_TFTPBOOT_DIR/pxelinux.cfg
+    sudo chown -R $STACK_USER:$LIBVIRT_GROUP $IRONIC_TFTPBOOT_DIR
 
     if [[ "$IRONIC_IPXE_ENABLED" == "True" ]] ; then
-        sudo mkdir -p $IRONIC_HTTP_DIR
-        sudo chown -R $STACK_USER:$LIBVIRT_GROUP $IRONIC_HTTP_DIR
+        sudo install -d -o $STACK_USER -g $LIBVIRT_GROUP $IRONIC_HTTP_DIR
     fi
 
-    sudo mkdir -p $IRONIC_DATA_DIR
-    sudo mkdir -p $IRONIC_STATE_PATH
-    sudo mkdir -p $IRONIC_TFTPBOOT_DIR
-    sudo chown -R $STACK_USER $IRONIC_DATA_DIR $IRONIC_STATE_PATH
-    sudo chown -R $STACK_USER:$LIBVIRT_GROUP $IRONIC_TFTPBOOT_DIR
-    mkdir -p $IRONIC_TFTPBOOT_DIR/pxelinux.cfg
-
     if [ ! -f $IRONIC_PXE_BOOT_IMAGE ]; then
         die $LINENO "PXE boot file $IRONIC_PXE_BOOT_IMAGE not found."
     fi
@@ -267,13 +260,12 @@
 # configure_ironic() - Set config files, create data dirs, etc
 function configure_ironic {
     configure_ironic_dirs
-    sudo chown $STACK_USER $IRONIC_CONF_DIR
 
     # Copy over ironic configuration file and configure common parameters.
     cp $IRONIC_DIR/etc/ironic/ironic.conf.sample $IRONIC_CONF_FILE
     iniset $IRONIC_CONF_FILE DEFAULT debug True
     inicomment $IRONIC_CONF_FILE DEFAULT log_file
-    iniset $IRONIC_CONF_FILE DEFAULT sql_connection `database_connection_url ironic`
+    iniset $IRONIC_CONF_FILE database connection `database_connection_url ironic`
     iniset $IRONIC_CONF_FILE DEFAULT state_path $IRONIC_STATE_PATH
     iniset $IRONIC_CONF_FILE DEFAULT use_syslog $SYSLOG
     # Configure Ironic conductor, if it was enabled.
@@ -427,6 +419,11 @@
 
 # init_ironic() - Initialize databases, etc.
 function init_ironic {
+    # Save private network as cleaning network
+    local cleaning_network_uuid
+    cleaning_network_uuid=$(neutron net-list | grep private | get_field 1)
+    iniset $IRONIC_CONF_FILE neutron cleaning_network_uuid ${cleaning_network_uuid}
+
     # (Re)create  ironic database
     recreate_database ironic
 
@@ -703,7 +700,7 @@
 
 function configure_ironic_auxiliary {
     configure_ironic_ssh_keypair
-    ironic_ssh_check $IRONIC_KEY_FILE $IRONIC_VM_SSH_ADDRESS $IRONIC_VM_SSH_PORT $IRONIC_SSH_USERNAME 10
+    ironic_ssh_check $IRONIC_KEY_FILE $IRONIC_VM_SSH_ADDRESS $IRONIC_VM_SSH_PORT $IRONIC_SSH_USERNAME $IRONIC_SSH_TIMEOUT
 }
 
 function build_ipa_coreos_ramdisk {
diff --git a/lib/keystone b/lib/keystone
index 89e9aa1..0dc8595 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -175,14 +175,10 @@
 
 # configure_keystone() - Set config files, create data dirs, etc
 function configure_keystone {
-    if [[ ! -d $KEYSTONE_CONF_DIR ]]; then
-        sudo mkdir -p $KEYSTONE_CONF_DIR
-    fi
-    sudo chown $STACK_USER $KEYSTONE_CONF_DIR
+    sudo install -d -o $STACK_USER $KEYSTONE_CONF_DIR
 
     if [[ "$KEYSTONE_CONF_DIR" != "$KEYSTONE_DIR/etc" ]]; then
-        cp -p $KEYSTONE_DIR/etc/keystone.conf.sample $KEYSTONE_CONF
-        chmod 600 $KEYSTONE_CONF
+        install -m 600 $KEYSTONE_DIR/etc/keystone.conf.sample $KEYSTONE_CONF
         cp -p $KEYSTONE_DIR/etc/policy.json $KEYSTONE_CONF_DIR
         if [[ -f "$KEYSTONE_DIR/etc/keystone-paste.ini" ]]; then
             cp -p "$KEYSTONE_DIR/etc/keystone-paste.ini" "$KEYSTONE_PASTE_INI"
@@ -229,13 +225,8 @@
     iniset_rpc_backend keystone $KEYSTONE_CONF
 
     # Set the URL advertised in the ``versions`` structure returned by the '/' route
-    if is_service_enabled tls-proxy; then
-        iniset $KEYSTONE_CONF DEFAULT public_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/"
-        iniset $KEYSTONE_CONF DEFAULT admin_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/"
-    else
-        iniset $KEYSTONE_CONF DEFAULT public_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:%(public_port)s/"
-        iniset $KEYSTONE_CONF DEFAULT admin_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:%(admin_port)s/"
-    fi
+    iniset $KEYSTONE_CONF DEFAULT public_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/"
+    iniset $KEYSTONE_CONF DEFAULT admin_endpoint "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/"
     iniset $KEYSTONE_CONF DEFAULT admin_bind_host "$KEYSTONE_ADMIN_BIND_HOST"
 
     # Register SSL certificates if provided
@@ -485,8 +476,7 @@
         $KEYSTONE_DIR/bin/keystone-manage pki_setup
 
         # Create cache dir
-        sudo mkdir -p $KEYSTONE_AUTH_CACHE_DIR
-        sudo chown $STACK_USER $KEYSTONE_AUTH_CACHE_DIR
+        sudo install -d -o $STACK_USER $KEYSTONE_AUTH_CACHE_DIR
         rm -f $KEYSTONE_AUTH_CACHE_DIR/*
     fi
 }
diff --git a/lib/lvm b/lib/lvm
index 39eed00..d0322c7 100644
--- a/lib/lvm
+++ b/lib/lvm
@@ -138,6 +138,31 @@
     fi
 }
 
+# set_lvm_filter() Gather all devices configured for LVM and
+# use them to build a global device filter
+# set_lvm_filter() Create a device filter
+# and add to /etc/lvm.conf.  Note this uses
+# all current PV's in use by LVM on the
+# system to build it's filter.
+#
+# Usage: set_lvm_filter()
+function set_lvm_filter {
+    local filter_suffix='"r|.*|" ]'
+    local filter_string="global_filter = [ "
+    local pv
+    local vg
+    local line
+
+    for pv_info in $(sudo pvs --noheadings -o name); do
+        pv=$(echo -e "${pv_info}" | sed 's/ //g' | sed 's/\/dev\///g')
+        new="\"a|$pv|\", "
+        filter_string=$filter_string$new
+    done
+    filter_string=$filter_string$filter_suffix
+
+    sudo sed -i "/# global_filter = \[*\]/a\    $global_filter$filter_string" /etc/lvm/lvm.conf
+    echo_summary "set lvm.conf device global_filter to: $filter_string"
+}
 
 # Restore xtrace
 $MY_XTRACE
diff --git a/lib/neutron b/lib/neutron
index a31a064..5ff3921 100755
--- a/lib/neutron
+++ b/lib/neutron
@@ -153,6 +153,7 @@
 # RHEL's support for namespaces requires using veths with ovs
 Q_OVS_USE_VETH=${Q_OVS_USE_VETH:-False}
 Q_USE_ROOTWRAP=${Q_USE_ROOTWRAP:-True}
+Q_USE_ROOTWRAP_DAEMON=$(trueorfalse True Q_USE_ROOTWRAP_DAEMON)
 # Meta data IP
 Q_META_DATA_IP=${Q_META_DATA_IP:-$SERVICE_HOST}
 # Allow Overlapping IP among subnets
@@ -226,6 +227,9 @@
 else
     NEUTRON_ROOTWRAP=$(get_rootwrap_location neutron)
     Q_RR_COMMAND="sudo $NEUTRON_ROOTWRAP $Q_RR_CONF_FILE"
+    if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
+        Q_RR_DAEMON_COMMAND="sudo $NEUTRON_ROOTWRAP-daemon $Q_RR_CONF_FILE"
+    fi
 fi
 
 
@@ -495,8 +499,7 @@
 # create_neutron_cache_dir() - Part of the _neutron_setup_keystone() process
 function create_neutron_cache_dir {
     # Create cache dir
-    sudo mkdir -p $NEUTRON_AUTH_CACHE_DIR
-    sudo chown $STACK_USER $NEUTRON_AUTH_CACHE_DIR
+    sudo install -d -o $STACK_USER $NEUTRON_AUTH_CACHE_DIR
     rm -f $NEUTRON_AUTH_CACHE_DIR/*
 }
 
@@ -800,10 +803,7 @@
 
 function _create_neutron_conf_dir {
     # Put config files in ``NEUTRON_CONF_DIR`` for everyone to find
-    if [[ ! -d $NEUTRON_CONF_DIR ]]; then
-        sudo mkdir -p $NEUTRON_CONF_DIR
-    fi
-    sudo chown $STACK_USER $NEUTRON_CONF_DIR
+    sudo install -d -o $STACK_USER $NEUTRON_CONF_DIR
 }
 
 # _configure_neutron_common()
@@ -896,6 +896,9 @@
     iniset $NEUTRON_TEST_CONFIG_FILE DEFAULT debug False
     iniset $NEUTRON_TEST_CONFIG_FILE DEFAULT use_namespaces $Q_USE_NAMESPACE
     iniset $NEUTRON_TEST_CONFIG_FILE agent root_helper "$Q_RR_COMMAND"
+    if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
+        iniset $NEUTRON_TEST_CONFIG_FILE agent root_helper_daemon "$Q_RR_DAEMON_COMMAND"
+    fi
 
     _neutron_setup_interface_driver $NEUTRON_TEST_CONFIG_FILE
 
@@ -910,6 +913,9 @@
     iniset $Q_DHCP_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
     iniset $Q_DHCP_CONF_FILE DEFAULT use_namespaces $Q_USE_NAMESPACE
     iniset $Q_DHCP_CONF_FILE DEFAULT root_helper "$Q_RR_COMMAND"
+    if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
+        iniset $NEUTRON_TEST_CONFIG_FILE agent root_helper_daemon "$Q_RR_DAEMON_COMMAND"
+    fi
 
     if ! is_service_enabled q-l3; then
         if [[ "$ENABLE_ISOLATED_METADATA" = "True" ]]; then
@@ -943,6 +949,9 @@
     iniset $Q_L3_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
     iniset $Q_L3_CONF_FILE DEFAULT use_namespaces $Q_USE_NAMESPACE
     iniset $Q_L3_CONF_FILE DEFAULT 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
 
@@ -956,6 +965,9 @@
     iniset $Q_META_CONF_FILE DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
     iniset $Q_META_CONF_FILE DEFAULT nova_metadata_ip $Q_META_DATA_IP
     iniset $Q_META_CONF_FILE DEFAULT root_helper "$Q_RR_COMMAND"
+    if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
+        iniset $Q_META_CONF_FILE agent root_helper_daemon "$Q_RR_DAEMON_COMMAND"
+    fi
 
     # Configures keystone for metadata_agent
     # The third argument "True" sets auth_url needed to communicate with keystone
@@ -1008,6 +1020,9 @@
     # Specify the default root helper prior to agent configuration to
     # ensure that an agent's configuration can override the default
     iniset /$Q_PLUGIN_CONF_FILE agent root_helper "$Q_RR_COMMAND"
+    if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE  agent root_helper_daemon "$Q_RR_DAEMON_COMMAND"
+    fi
     iniset $NEUTRON_CONF DEFAULT verbose True
     iniset $NEUTRON_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
 
@@ -1075,10 +1090,8 @@
 # _neutron_deploy_rootwrap_filters() - deploy rootwrap filters to $Q_CONF_ROOTWRAP_D (owned by root).
 function _neutron_deploy_rootwrap_filters {
     local srcdir=$1
-    mkdir -p -m 755 $Q_CONF_ROOTWRAP_D
-    sudo cp -pr $srcdir/etc/neutron/rootwrap.d/* $Q_CONF_ROOTWRAP_D/
-    sudo chown -R root:root $Q_CONF_ROOTWRAP_D
-    sudo chmod 644 $Q_CONF_ROOTWRAP_D/*
+    sudo install -d -o root -m 755 $Q_CONF_ROOTWRAP_D
+    sudo install -o root -m 644 $srcdir/etc/neutron/rootwrap.d/* $Q_CONF_ROOTWRAP_D/
 }
 
 # _neutron_setup_rootwrap() - configure Neutron's rootwrap
@@ -1097,25 +1110,28 @@
     # Set up ``rootwrap.conf``, pointing to ``$NEUTRON_CONF_DIR/rootwrap.d``
     # location moved in newer versions, prefer new location
     if test -r $NEUTRON_DIR/etc/neutron/rootwrap.conf; then
-        sudo cp -p $NEUTRON_DIR/etc/neutron/rootwrap.conf $Q_RR_CONF_FILE
+        sudo install -o root -g root -m 644 $NEUTRON_DIR/etc/neutron/rootwrap.conf $Q_RR_CONF_FILE
     else
-        sudo cp -p $NEUTRON_DIR/etc/rootwrap.conf $Q_RR_CONF_FILE
+        sudo install -o root -g root -m 644 $NEUTRON_DIR/etc/rootwrap.conf $Q_RR_CONF_FILE
     fi
     sudo sed -e "s:^filters_path=.*$:filters_path=$Q_CONF_ROOTWRAP_D:" -i $Q_RR_CONF_FILE
-    sudo chown root:root $Q_RR_CONF_FILE
-    sudo chmod 0644 $Q_RR_CONF_FILE
     # Specify ``rootwrap.conf`` as first parameter to neutron-rootwrap
     ROOTWRAP_SUDOER_CMD="$NEUTRON_ROOTWRAP $Q_RR_CONF_FILE *"
+    ROOTWRAP_DAEMON_SUDOER_CMD="$NEUTRON_ROOTWRAP-daemon $Q_RR_CONF_FILE"
 
     # Set up the rootwrap sudoers for neutron
     TEMPFILE=`mktemp`
     echo "$STACK_USER ALL=(root) NOPASSWD: $ROOTWRAP_SUDOER_CMD" >$TEMPFILE
+    echo "$STACK_USER ALL=(root) NOPASSWD: $ROOTWRAP_DAEMON_SUDOER_CMD" >>$TEMPFILE
     chmod 0440 $TEMPFILE
     sudo chown root:root $TEMPFILE
     sudo mv $TEMPFILE /etc/sudoers.d/neutron-rootwrap
 
     # Update the root_helper
     iniset $NEUTRON_CONF agent root_helper "$Q_RR_COMMAND"
+    if [[ "$Q_USE_ROOTWRAP_DAEMON" == "True" ]]; then
+        iniset $NEUTRON_CONF agent root_helper_daemon "$Q_RR_DAEMON_COMMAND"
+    fi
 }
 
 # Configures keystone integration for neutron service and agents
diff --git a/lib/nova b/lib/nova
index f049095..7fbade0 100644
--- a/lib/nova
+++ b/lib/nova
@@ -232,16 +232,15 @@
     if [[ -d $NOVA_CONF_DIR/rootwrap.d ]]; then
         sudo rm -rf $NOVA_CONF_DIR/rootwrap.d
     fi
+
     # Deploy filters to /etc/nova/rootwrap.d
-    sudo mkdir -m 755 $NOVA_CONF_DIR/rootwrap.d
-    sudo cp $NOVA_DIR/etc/nova/rootwrap.d/*.filters $NOVA_CONF_DIR/rootwrap.d
-    sudo chown -R root:root $NOVA_CONF_DIR/rootwrap.d
-    sudo chmod 644 $NOVA_CONF_DIR/rootwrap.d/*
+    sudo install -d -o root -g root -m 755 $NOVA_CONF_DIR/rootwrap.d
+    sudo install -o root -g root -m 644  $NOVA_DIR/etc/nova/rootwrap.d/*.filters $NOVA_CONF_DIR/rootwrap.d
+
     # Set up rootwrap.conf, pointing to /etc/nova/rootwrap.d
-    sudo cp $NOVA_DIR/etc/nova/rootwrap.conf $NOVA_CONF_DIR/
+    sudo install -o root -g root -m 644 $NOVA_DIR/etc/nova/rootwrap.conf $NOVA_CONF_DIR
     sudo sed -e "s:^filters_path=.*$:filters_path=$NOVA_CONF_DIR/rootwrap.d:" -i $NOVA_CONF_DIR/rootwrap.conf
-    sudo chown root:root $NOVA_CONF_DIR/rootwrap.conf
-    sudo chmod 0644 $NOVA_CONF_DIR/rootwrap.conf
+
     # Specify rootwrap.conf as first parameter to nova-rootwrap
     local rootwrap_sudoer_cmd="$NOVA_ROOTWRAP $NOVA_CONF_DIR/rootwrap.conf *"
 
@@ -256,12 +255,9 @@
 # configure_nova() - Set config files, create data dirs, etc
 function configure_nova {
     # Put config files in ``/etc/nova`` for everyone to find
-    if [[ ! -d $NOVA_CONF_DIR ]]; then
-        sudo mkdir -p $NOVA_CONF_DIR
-    fi
-    sudo chown $STACK_USER $NOVA_CONF_DIR
+    sudo install -d -o $STACK_USER $NOVA_CONF_DIR
 
-    cp -p $NOVA_DIR/etc/nova/policy.json $NOVA_CONF_DIR
+    install_default_policy nova
 
     configure_nova_rootwrap
 
@@ -318,8 +314,7 @@
         # ----------------
 
         # Nova stores each instance in its own directory.
-        sudo mkdir -p $NOVA_INSTANCES_PATH
-        sudo chown -R $STACK_USER $NOVA_INSTANCES_PATH
+        sudo install -d -o $STACK_USER $NOVA_INSTANCES_PATH
 
         # You can specify a different disk to be mounted and used for backing the
         # virtual machines.  If there is a partition labeled nova-instances we
@@ -437,7 +432,7 @@
     iniset $NOVA_CONF DEFAULT s3_host "$SERVICE_HOST"
     iniset $NOVA_CONF DEFAULT s3_port "$S3_SERVICE_PORT"
     iniset $NOVA_CONF DEFAULT my_ip "$HOST_IP"
-    iniset $NOVA_CONF DEFAULT sql_connection `database_connection_url nova`
+    iniset $NOVA_CONF database connection `database_connection_url nova`
     iniset $NOVA_CONF DEFAULT instance_name_template "${INSTANCE_NAME_PREFIX}%08x"
     iniset $NOVA_CONF osapi_v3 enabled "True"
 
@@ -471,7 +466,7 @@
 
     if [ -n "$NOVA_STATE_PATH" ]; then
         iniset $NOVA_CONF DEFAULT state_path "$NOVA_STATE_PATH"
-        iniset $NOVA_CONF DEFAULT lock_path "$NOVA_STATE_PATH"
+        iniset $NOVA_CONF oslo_concurrency lock_path "$NOVA_STATE_PATH"
     fi
     if [ -n "$NOVA_INSTANCES_PATH" ]; then
         iniset $NOVA_CONF DEFAULT instances_path "$NOVA_INSTANCES_PATH"
@@ -577,7 +572,7 @@
 function init_nova_cells {
     if is_service_enabled n-cell; then
         cp $NOVA_CONF $NOVA_CELLS_CONF
-        iniset $NOVA_CELLS_CONF DEFAULT sql_connection `database_connection_url $NOVA_CELLS_DB`
+        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 DEFAULT dhcpbridge_flagfile $NOVA_CELLS_CONF
         iniset $NOVA_CELLS_CONF cells enable True
@@ -603,8 +598,7 @@
 # create_nova_cache_dir() - Part of the init_nova() process
 function create_nova_cache_dir {
     # Create cache dir
-    sudo mkdir -p $NOVA_AUTH_CACHE_DIR
-    sudo chown $STACK_USER $NOVA_AUTH_CACHE_DIR
+    sudo install -d -o $STACK_USER $NOVA_AUTH_CACHE_DIR
     rm -f $NOVA_AUTH_CACHE_DIR/*
 }
 
@@ -621,8 +615,7 @@
 # create_nova_keys_dir() - Part of the init_nova() process
 function create_nova_keys_dir {
     # Create keys dir
-    sudo mkdir -p ${NOVA_STATE_PATH}/keys
-    sudo chown -R $STACK_USER ${NOVA_STATE_PATH}
+    sudo install -d -o $STACK_USER ${NOVA_STATE_PATH} ${NOVA_STATE_PATH}/keys
 }
 
 # init_nova() - Initialize databases, etc.
diff --git a/lib/rpc_backend b/lib/rpc_backend
index 32c3e17..3d4ef76 100644
--- a/lib/rpc_backend
+++ b/lib/rpc_backend
@@ -233,6 +233,15 @@
     fi
 }
 
+# builds transport url string
+function get_transport_url {
+    if is_service_enabled qpid || [ -n "$QPID_HOST" ]; then
+        echo "qpid://$QPID_USERNAME:$QPID_PASSWORD@$QPID_HOST:5672/"
+    elif is_service_enabled rabbit || { [ -n "$RABBIT_HOST" ] && [ -n "$RABBIT_PASSWORD" ]; }; then
+        echo "rabbit://$RABBIT_USERID:$RABBIT_PASSWORD@$RABBIT_HOST:5672/"
+    fi
+}
+
 # iniset cofiguration
 function iniset_rpc_backend {
     local package=$1
diff --git a/lib/sahara b/lib/sahara
index 7c22d0f..a965f55 100644
--- a/lib/sahara
+++ b/lib/sahara
@@ -101,23 +101,14 @@
 
 # configure_sahara() - Set config files, create data dirs, etc
 function configure_sahara {
-
-    if [[ ! -d $SAHARA_CONF_DIR ]]; then
-        sudo mkdir -p $SAHARA_CONF_DIR
-    fi
-    sudo chown $STACK_USER $SAHARA_CONF_DIR
+    sudo install -d -o $STACK_USER $SAHARA_CONF_DIR
 
     if [[ -f $SAHARA_DIR/etc/sahara/policy.json ]]; then
         cp -p $SAHARA_DIR/etc/sahara/policy.json $SAHARA_CONF_DIR
     fi
 
-    # Copy over sahara configuration file and configure common parameters.
-    cp $SAHARA_DIR/etc/sahara/sahara.conf.sample $SAHARA_CONF_FILE
-
     # Create auth cache dir
-    sudo mkdir -p $SAHARA_AUTH_CACHE_DIR
-    sudo chown $STACK_USER $SAHARA_AUTH_CACHE_DIR
-    sudo chmod 700 $SAHARA_AUTH_CACHE_DIR
+    sudo install -d -o $STACK_USER -m 700 $SAHARA_AUTH_CACHE_DIR
     rm -rf $SAHARA_AUTH_CACHE_DIR/*
 
     configure_auth_token_middleware $SAHARA_CONF_FILE sahara $SAHARA_AUTH_CACHE_DIR
diff --git a/lib/swift b/lib/swift
index 4a63500..af19c68 100644
--- a/lib/swift
+++ b/lib/swift
@@ -306,8 +306,8 @@
     # Make sure to kill all swift processes first
     swift-init --run-dir=${SWIFT_DATA_DIR}/run all stop || true
 
-    sudo mkdir -p ${SWIFT_CONF_DIR}/{object,container,account}-server
-    sudo chown -R ${STACK_USER}: ${SWIFT_CONF_DIR}
+    sudo install -d -o ${STACK_USER} ${SWIFT_CONF_DIR}
+    sudo install -d -o ${STACK_USER} ${SWIFT_CONF_DIR}/{object,container,account}-server
 
     if [[ "$SWIFT_CONF_DIR" != "/etc/swift" ]]; then
         # Some swift tools are hard-coded to use ``/etc/swift`` and are apparently not going to be fixed.
@@ -378,7 +378,11 @@
     # Configure Ceilometer
     if is_service_enabled ceilometer; then
         iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:ceilometer "set log_level" "WARN"
-        iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:ceilometer use "egg:ceilometer#swift"
+        iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:ceilometer paste.filter_factory "ceilometermiddleware.swift:filter_factory"
+        iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:ceilometer control_exchange "swift"
+        iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:ceilometer url $(get_transport_url)
+        iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:ceilometer driver "messaging"
+        iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:ceilometer topic "notifications"
         SWIFT_EXTRAS_MIDDLEWARE_LAST="${SWIFT_EXTRAS_MIDDLEWARE_LAST} ceilometer"
     fi
 
@@ -415,16 +419,8 @@
     # IDs will included in all of its log messages.
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken log_name swift
 
-    # NOTE(jamielennox): swift cannot use the regular configure_auth_token_middleware function because swift
-    # doesn't use oslo.config which is the only way to configure auth plugins with the middleare.
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken paste.filter_factory keystonemiddleware.auth_token:filter_factory
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken identity_uri $KEYSTONE_AUTH_URI
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken admin_user swift
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken admin_password $SERVICE_PASSWORD
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken admin_tenant_name $SERVICE_TENANT_NAME
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken auth_uri $KEYSTONE_SERVICE_URI
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken cafile $SSL_BUNDLE_FILE
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken signing_dir $SWIFT_AUTH_CACHE_DIR
+    configure_auth_token_middleware $SWIFT_CONFIG_PROXY_SERVER swift $SWIFT_AUTH_CACHE_DIR filter:authtoken
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken delay_auth_decision 1
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken cache swift.cache
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:authtoken include_service_catalog False
@@ -534,8 +530,7 @@
     # changing the permissions so we can run it as our user.
 
     local user_group=$(id -g ${STACK_USER})
-    sudo mkdir -p ${SWIFT_DATA_DIR}/{drives,cache,run,logs}
-    sudo chown -R ${STACK_USER}:${user_group} ${SWIFT_DATA_DIR}
+    sudo install -d -o ${STACK_USER} -g ${user_group} ${SWIFT_DATA_DIR}/{drives,cache,run,logs}
 
     # Create a loopback disk and format it to XFS.
     if [[ -e ${SWIFT_DISK_IMAGE} ]]; then
@@ -675,8 +670,7 @@
     } && popd >/dev/null
 
     # Create cache dir
-    sudo mkdir -p $SWIFT_AUTH_CACHE_DIR
-    sudo chown $STACK_USER $SWIFT_AUTH_CACHE_DIR
+    sudo install -d -o ${STACK_USER} $SWIFT_AUTH_CACHE_DIR
     rm -f $SWIFT_AUTH_CACHE_DIR/*
 }
 
diff --git a/lib/tempest b/lib/tempest
index f856ce0..443915c 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -66,7 +66,7 @@
 # This must be False on stable branches, as master tempest
 # deps do not match stable branch deps. Set this to True to
 # have tempest installed in devstack by default.
-INSTALL_TEMPEST=${INSTALL_TEMPEST:-"False"}
+INSTALL_TEMPEST=${INSTALL_TEMPEST:-"True"}
 
 
 BOTO_MATERIALS_PATH="$FILES/images/s3-materials/cirros-${CIRROS_VERSION}"
@@ -170,12 +170,8 @@
 
     # Create tempest.conf from tempest.conf.sample
     # copy every time, because the image UUIDS are going to change
-    if [[ ! -d $TEMPEST_CONFIG_DIR ]]; then
-        sudo mkdir -p $TEMPEST_CONFIG_DIR
-    fi
-    sudo chown $STACK_USER $TEMPEST_CONFIG_DIR
-    cp $TEMPEST_DIR/etc/tempest.conf.sample $TEMPEST_CONFIG
-    chmod 644 $TEMPEST_CONFIG
+    sudo install -d -o $STACK_USER $TEMPEST_CONFIG_DIR
+    install -m 644 $TEMPEST_DIR/etc/tempest.conf.sample $TEMPEST_CONFIG
 
     password=${ADMIN_PASSWORD:-secrete}
 
@@ -275,7 +271,7 @@
 
     iniset $TEMPEST_CONFIG DEFAULT use_syslog $SYSLOG
     # Oslo
-    iniset $TEMPEST_CONFIG DEFAULT lock_path $TEMPEST_STATE_PATH
+    iniset $TEMPEST_CONFIG oslo_concurrency lock_path $TEMPEST_STATE_PATH
     mkdir -p $TEMPEST_STATE_PATH
     iniset $TEMPEST_CONFIG DEFAULT use_stderr False
     iniset $TEMPEST_CONFIG DEFAULT log_file tempest.log
@@ -315,6 +311,9 @@
 
     # Auth
     iniset $TEMPEST_CONFIG auth allow_tenant_isolation ${TEMPEST_ALLOW_TENANT_ISOLATION:-True}
+    if [[ "$TEMPEST_AUTH_VERSION" == "v3" ]]; then
+        iniset $TEMPEST_CONFIG auth tempest_roles "Member"
+    fi
 
     # Compute
     iniset $TEMPEST_CONFIG compute ssh_user ${DEFAULT_INSTANCE_USER:-cirros} # DEPRECATED
@@ -349,6 +348,8 @@
     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
 
     # Compute admin
     iniset $TEMPEST_CONFIG "compute-admin" username $ADMIN_USERNAME
@@ -396,6 +397,7 @@
         fi
         iniset $TEMPEST_CONFIG orchestration instance_type "m1.heat"
         iniset $TEMPEST_CONFIG orchestration build_timeout 900
+        iniset $TEMPEST_CONFIG orchestration stack_owner_role "_member_"
     fi
 
     # Scenario
diff --git a/lib/trove b/lib/trove
index d777983..4c5a438 100644
--- a/lib/trove
+++ b/lib/trove
@@ -44,8 +44,8 @@
 TROVE_LOCAL_API_PASTE_INI=$TROVE_LOCAL_CONF_DIR/api-paste.ini
 TROVE_AUTH_CACHE_DIR=${TROVE_AUTH_CACHE_DIR:-/var/cache/trove}
 TROVE_DATASTORE_TYPE=${TROVE_DATASTORE_TYPE:-"mysql"}
-TROVE_DATASTORE_VERSION=${TROVE_DATASTORE_VERSION:-"5.5"}
-TROVE_DATASTORE_PACKAGE=${TROVE_DATASTORE_PACKAGE:-"mysql-server-5.5"}
+TROVE_DATASTORE_VERSION=${TROVE_DATASTORE_VERSION:-"5.6"}
+TROVE_DATASTORE_PACKAGE=${TROVE_DATASTORE_PACKAGE:-"mysql-server-5.6"}
 
 # Support entry points installation of console scripts
 if [[ -d $TROVE_DIR/bin ]]; then
@@ -121,10 +121,7 @@
     setup_develop $TROVE_DIR
 
     # Create the trove conf dir and cache dirs if they don't exist
-    sudo mkdir -p ${TROVE_CONF_DIR}
-    sudo mkdir -p ${TROVE_AUTH_CACHE_DIR}
-    sudo chown -R $STACK_USER: ${TROVE_CONF_DIR}
-    sudo chown -R $STACK_USER: ${TROVE_AUTH_CACHE_DIR}
+    sudo install -d -o $STACK_USER ${TROVE_CONF_DIR} ${TROVE_AUTH_CACHE_DIR}
 
     # Copy api-paste file over to the trove conf dir
     cp $TROVE_LOCAL_API_PASTE_INI $TROVE_API_PASTE_INI
@@ -136,7 +133,7 @@
 
     iniset $TROVE_CONF DEFAULT rabbit_userid $RABBIT_USERID
     iniset $TROVE_CONF DEFAULT rabbit_password $RABBIT_PASSWORD
-    iniset $TROVE_CONF DEFAULT sql_connection `database_connection_url trove`
+    iniset $TROVE_CONF database connection `database_connection_url trove`
     iniset $TROVE_CONF DEFAULT default_datastore $TROVE_DATASTORE_TYPE
     setup_trove_logging $TROVE_CONF
     iniset $TROVE_CONF DEFAULT trove_api_workers "$API_WORKERS"
@@ -149,7 +146,7 @@
 
         iniset $TROVE_TASKMANAGER_CONF DEFAULT rabbit_userid $RABBIT_USERID
         iniset $TROVE_TASKMANAGER_CONF DEFAULT rabbit_password $RABBIT_PASSWORD
-        iniset $TROVE_TASKMANAGER_CONF DEFAULT sql_connection `database_connection_url trove`
+        iniset $TROVE_TASKMANAGER_CONF database connection `database_connection_url trove`
         iniset $TROVE_TASKMANAGER_CONF DEFAULT taskmanager_manager trove.taskmanager.manager.Manager
         iniset $TROVE_TASKMANAGER_CONF DEFAULT nova_proxy_admin_user radmin
         iniset $TROVE_TASKMANAGER_CONF DEFAULT nova_proxy_admin_tenant_name trove
@@ -162,7 +159,7 @@
     if is_service_enabled tr-cond; then
         iniset $TROVE_CONDUCTOR_CONF DEFAULT rabbit_userid $RABBIT_USERID
         iniset $TROVE_CONDUCTOR_CONF DEFAULT rabbit_password $RABBIT_PASSWORD
-        iniset $TROVE_CONDUCTOR_CONF DEFAULT sql_connection `database_connection_url trove`
+        iniset $TROVE_CONDUCTOR_CONF database connection `database_connection_url trove`
         iniset $TROVE_CONDUCTOR_CONF DEFAULT nova_proxy_admin_user radmin
         iniset $TROVE_CONDUCTOR_CONF DEFAULT nova_proxy_admin_tenant_name trove
         iniset $TROVE_CONDUCTOR_CONF DEFAULT nova_proxy_admin_pass $RADMIN_USER_PASS
diff --git a/lib/zaqar b/lib/zaqar
index 02b6987..34f1915 100644
--- a/lib/zaqar
+++ b/lib/zaqar
@@ -105,8 +105,7 @@
 function configure_zaqar {
     setup_develop $ZAQAR_DIR
 
-    [ ! -d $ZAQAR_CONF_DIR ] && sudo mkdir -m 755 -p $ZAQAR_CONF_DIR
-    sudo chown $USER $ZAQAR_CONF_DIR
+    sudo install -d -o $STACK_USER -m 755 $ZAQAR_CONF_DIR
 
     iniset $ZAQAR_CONF DEFAULT debug True
     iniset $ZAQAR_CONF DEFAULT verbose True
@@ -168,8 +167,7 @@
 # init_zaqar() - Initialize etc.
 function init_zaqar {
     # Create cache dir
-    sudo mkdir -p $ZAQAR_AUTH_CACHE_DIR
-    sudo chown $STACK_USER $ZAQAR_AUTH_CACHE_DIR
+    sudo install -d -o $STACK_USER $ZAQAR_AUTH_CACHE_DIR
     rm -f $ZAQAR_AUTH_CACHE_DIR/*
 }
 
diff --git a/samples/local.conf b/samples/local.conf
index e4052c2..63000b6 100644
--- a/samples/local.conf
+++ b/samples/local.conf
@@ -98,4 +98,4 @@
 # -------
 
 # Install the tempest test suite
-enable_service tempest
\ No newline at end of file
+enable_service tempest
diff --git a/stack.sh b/stack.sh
index 615b77f..d83952a 100755
--- a/stack.sh
+++ b/stack.sh
@@ -746,6 +746,9 @@
 fi
 
 if is_service_enabled s-proxy; then
+    if is_service_enabled ceilometer; then
+        install_ceilometermiddleware
+    fi
     stack_install_service swift
     configure_swift
 
@@ -975,7 +978,7 @@
         create_swift_accounts
     fi
 
-    if is_service_enabled heat && [[ "$HEAT_STANDALONE" != "True" ]]; then
+    if is_service_enabled heat; then
         create_heat_accounts
     fi
 
@@ -1313,6 +1316,15 @@
 # Prepare bash completion for OSC
 openstack complete | sudo tee /etc/bash_completion.d/osc.bash_completion > /dev/null
 
+# If cinder is configured, set global_filter for PV devices
+if is_service_enabled cinder; then
+    if is_ubuntu; then
+        echo_summary "Configuring lvm.conf global device filter"
+        set_lvm_filter
+    else
+        echo_summary "Skip setting lvm filters for non Ubuntu systems"
+    fi
+fi
 
 # Fin
 # ===
diff --git a/tools/install_prereqs.sh b/tools/install_prereqs.sh
index 303cc63..917980c 100755
--- a/tools/install_prereqs.sh
+++ b/tools/install_prereqs.sh
@@ -62,6 +62,8 @@
 
 # Install package requirements
 PACKAGES=$(get_packages general $ENABLED_SERVICES)
+PACKAGES="$PACKAGES $(get_plugin_packages)"
+
 if is_ubuntu && echo $PACKAGES | grep -q dkms ; then
     # ensure headers for the running kernel are installed for any DKMS builds
     PACKAGES="$PACKAGES linux-headers-$(uname -r)"