Merge "Confirm network is created before setting public_network_id"
diff --git a/clean.sh b/clean.sh
index d92807c..e369eda 100755
--- a/clean.sh
+++ b/clean.sh
@@ -49,7 +49,6 @@
 source $TOP_DIR/lib/placement
 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
 
@@ -108,7 +107,7 @@
 fi
 
 # Clean out /etc
-sudo rm -rf /etc/keystone /etc/glance /etc/nova /etc/cinder /etc/swift /etc/heat /etc/neutron /etc/openstack/
+sudo rm -rf /etc/keystone /etc/glance /etc/nova /etc/cinder /etc/swift /etc/neutron /etc/openstack/
 
 # Clean out tgt
 sudo rm -f /etc/tgt/conf.d/*
diff --git a/doc/source/guides/devstack-with-nested-kvm.rst b/doc/source/guides/devstack-with-nested-kvm.rst
index 85a5656..3732f06 100644
--- a/doc/source/guides/devstack-with-nested-kvm.rst
+++ b/doc/source/guides/devstack-with-nested-kvm.rst
@@ -73,7 +73,7 @@
 ::
 
     sudo rmmod kvm-amd
-    sudo sh -c "echo 'options amd nested=1' >> /etc/modprobe.d/dist.conf"
+    sudo sh -c "echo 'options kvm-amd nested=1' >> /etc/modprobe.d/dist.conf"
     sudo modprobe kvm-amd
 
 Ensure the Nested KVM Kernel module parameter for AMD is enabled on the
diff --git a/doc/source/plugin-registry.rst b/doc/source/plugin-registry.rst
index 6ece997..4cfbcb1 100644
--- a/doc/source/plugin-registry.rst
+++ b/doc/source/plugin-registry.rst
@@ -58,6 +58,7 @@
 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>`__
+fuxi                                   `git://git.openstack.org/openstack/fuxi <https://git.openstack.org/cgit/openstack/fuxi>`__
 gce-api                                `git://git.openstack.org/openstack/gce-api <https://git.openstack.org/cgit/openstack/gce-api>`__
 glare                                  `git://git.openstack.org/openstack/glare <https://git.openstack.org/cgit/openstack/glare>`__
 gnocchi                                `git://git.openstack.org/openstack/gnocchi <https://git.openstack.org/cgit/openstack/gnocchi>`__
@@ -76,9 +77,12 @@
 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>`__
+manila-ui                              `git://git.openstack.org/openstack/manila-ui <https://git.openstack.org/cgit/openstack/manila-ui>`__
 masakari                               `git://git.openstack.org/openstack/masakari <https://git.openstack.org/cgit/openstack/masakari>`__
+meteos                                 `git://git.openstack.org/openstack/meteos <https://git.openstack.org/cgit/openstack/meteos>`__
 mistral                                `git://git.openstack.org/openstack/mistral <https://git.openstack.org/cgit/openstack/mistral>`__
 mixmatch                               `git://git.openstack.org/openstack/mixmatch <https://git.openstack.org/cgit/openstack/mixmatch>`__
+mogan                                  `git://git.openstack.org/openstack/mogan <https://git.openstack.org/cgit/openstack/mogan>`__
 monasca-analytics                      `git://git.openstack.org/openstack/monasca-analytics <https://git.openstack.org/cgit/openstack/monasca-analytics>`__
 monasca-api                            `git://git.openstack.org/openstack/monasca-api <https://git.openstack.org/cgit/openstack/monasca-api>`__
 monasca-ceilometer                     `git://git.openstack.org/openstack/monasca-ceilometer <https://git.openstack.org/cgit/openstack/monasca-ceilometer>`__
@@ -92,6 +96,8 @@
 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-cumulus                     `git://git.openstack.org/openstack/networking-cumulus <https://git.openstack.org/cgit/openstack/networking-cumulus>`__
+networking-dpm                         `git://git.openstack.org/openstack/networking-dpm <https://git.openstack.org/cgit/openstack/networking-dpm>`__
 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-huawei                      `git://git.openstack.org/openstack/networking-huawei <https://git.openstack.org/cgit/openstack/networking-huawei>`__
@@ -116,15 +122,17 @@
 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>`__
-nimble                                 `git://git.openstack.org/openstack/nimble <https://git.openstack.org/cgit/openstack/nimble>`__
 nova-docker                            `git://git.openstack.org/openstack/nova-docker <https://git.openstack.org/cgit/openstack/nova-docker>`__
+nova-dpm                               `git://git.openstack.org/openstack/nova-dpm <https://git.openstack.org/cgit/openstack/nova-dpm>`__
 nova-lxd                               `git://git.openstack.org/openstack/nova-lxd <https://git.openstack.org/cgit/openstack/nova-lxd>`__
 nova-mksproxy                          `git://git.openstack.org/openstack/nova-mksproxy <https://git.openstack.org/cgit/openstack/nova-mksproxy>`__
 nova-powervm                           `git://git.openstack.org/openstack/nova-powervm <https://git.openstack.org/cgit/openstack/nova-powervm>`__
 oaktree                                `git://git.openstack.org/openstack/oaktree <https://git.openstack.org/cgit/openstack/oaktree>`__
 octavia                                `git://git.openstack.org/openstack/octavia <https://git.openstack.org/cgit/openstack/octavia>`__
+os-xenapi                              `git://git.openstack.org/openstack/os-xenapi <https://git.openstack.org/cgit/openstack/os-xenapi>`__
 osprofiler                             `git://git.openstack.org/openstack/osprofiler <https://git.openstack.org/cgit/openstack/osprofiler>`__
 panko                                  `git://git.openstack.org/openstack/panko <https://git.openstack.org/cgit/openstack/panko>`__
+picasso                                `git://git.openstack.org/openstack/picasso <https://git.openstack.org/cgit/openstack/picasso>`__
 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>`__
diff --git a/doc/source/plugins.rst b/doc/source/plugins.rst
index 31987bc..5b3c6cf 100644
--- a/doc/source/plugins.rst
+++ b/doc/source/plugins.rst
@@ -99,7 +99,7 @@
       should exist at this point.
    -  **extra** - Called near the end after layer 1 and 2 services have
       been started.
-   - **test-config** - Called at the end of devstack used to configure tempest
+   -  **test-config** - Called at the end of devstack used to configure tempest
       or any other test environments
 
 -  **unstack** - Called by ``unstack.sh`` before other services are shut
diff --git a/files/apache-heat-api-cfn.template b/files/apache-heat-api-cfn.template
deleted file mode 100644
index ab33c66..0000000
--- a/files/apache-heat-api-cfn.template
+++ /dev/null
@@ -1,27 +0,0 @@
-Listen %PUBLICPORT%
-
-<VirtualHost *:%PUBLICPORT%>
-    WSGIDaemonProcess heat-api-cfn processes=2 threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
-    WSGIProcessGroup heat-api-cfn
-    WSGIScriptAlias / %HEAT_BIN_DIR%/heat-wsgi-api-cfn
-    WSGIApplicationGroup %{GLOBAL}
-    WSGIPassAuthorization On
-    AllowEncodedSlashes On
-    <IfVersion >= 2.4>
-      ErrorLogFormat "%{cu}t %M"
-    </IfVersion>
-    ErrorLog /var/log/%APACHE_NAME%/heat-api-cfn.log
-    %SSLENGINE%
-    %SSLCERTFILE%
-    %SSLKEYFILE%
-
-    <Directory %HEAT_BIN_DIR%>
-        <IfVersion >= 2.4>
-            Require all granted
-        </IfVersion>
-        <IfVersion < 2.4>
-            Order allow,deny
-            Allow from all
-        </IfVersion>
-    </Directory>
-</VirtualHost>
diff --git a/files/apache-heat-api-cloudwatch.template b/files/apache-heat-api-cloudwatch.template
deleted file mode 100644
index 06c91bb..0000000
--- a/files/apache-heat-api-cloudwatch.template
+++ /dev/null
@@ -1,27 +0,0 @@
-Listen %PUBLICPORT%
-
-<VirtualHost *:%PUBLICPORT%>
-    WSGIDaemonProcess heat-api-cloudwatch processes=2 threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
-    WSGIProcessGroup heat-api-cloudwatch
-    WSGIScriptAlias / %HEAT_BIN_DIR%/heat-wsgi-api-cloudwatch
-    WSGIApplicationGroup %{GLOBAL}
-    WSGIPassAuthorization On
-    AllowEncodedSlashes On
-    <IfVersion >= 2.4>
-      ErrorLogFormat "%{cu}t %M"
-    </IfVersion>
-    ErrorLog /var/log/%APACHE_NAME%/heat-api-cloudwatch.log
-    %SSLENGINE%
-    %SSLCERTFILE%
-    %SSLKEYFILE%
-
-    <Directory %HEAT_BIN_DIR%>
-        <IfVersion >= 2.4>
-            Require all granted
-        </IfVersion>
-        <IfVersion < 2.4>
-            Order allow,deny
-            Allow from all
-        </IfVersion>
-    </Directory>
-</VirtualHost>
diff --git a/files/apache-heat-api.template b/files/apache-heat-api.template
deleted file mode 100644
index 4924b39..0000000
--- a/files/apache-heat-api.template
+++ /dev/null
@@ -1,27 +0,0 @@
-Listen %PUBLICPORT%
-
-<VirtualHost *:%PUBLICPORT%>
-    WSGIDaemonProcess heat-api processes=3 threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
-    WSGIProcessGroup heat-api
-    WSGIScriptAlias / %HEAT_BIN_DIR%/heat-wsgi-api
-    WSGIApplicationGroup %{GLOBAL}
-    WSGIPassAuthorization On
-    AllowEncodedSlashes On
-    <IfVersion >= 2.4>
-      ErrorLogFormat "%{cu}t %M"
-    </IfVersion>
-    ErrorLog /var/log/%APACHE_NAME%/heat-api.log
-    %SSLENGINE%
-    %SSLCERTFILE%
-    %SSLKEYFILE%
-
-    <Directory %HEAT_BIN_DIR%>
-        <IfVersion >= 2.4>
-            Require all granted
-        </IfVersion>
-        <IfVersion < 2.4>
-            Order allow,deny
-            Allow from all
-        </IfVersion>
-    </Directory>
-</VirtualHost>
diff --git a/files/apache-heat-pip-repo.template b/files/apache-heat-pip-repo.template
deleted file mode 100644
index d88ac3e..0000000
--- a/files/apache-heat-pip-repo.template
+++ /dev/null
@@ -1,15 +0,0 @@
-Listen %HEAT_PIP_REPO_PORT%
-
-<VirtualHost *:%HEAT_PIP_REPO_PORT%>
-    DocumentRoot %HEAT_PIP_REPO%
-    <Directory %HEAT_PIP_REPO%>
-        DirectoryIndex index.html
-        Require all granted
-        Order allow,deny
-        allow from all
-    </Directory>
-
-    ErrorLog /var/log/%APACHE_NAME%/heat_pip_repo_error.log
-    LogLevel warn
-    CustomLog /var/log/%APACHE_NAME%/heat_pip_repo_access.log combined
-</VirtualHost>
diff --git a/files/apache-keystone.template b/files/apache-keystone.template
index 428544f..84dc273 100644
--- a/files/apache-keystone.template
+++ b/files/apache-keystone.template
@@ -34,6 +34,12 @@
     %SSLKEYFILE%
 </VirtualHost>
 
+%SSLLISTEN%<VirtualHost *:443>
+%SSLLISTEN%    %SSLENGINE%
+%SSLLISTEN%    %SSLCERTFILE%
+%SSLLISTEN%    %SSLKEYFILE%
+%SSLLISTEN%</VirtualHost>
+
 Alias /identity %KEYSTONE_BIN%/keystone-wsgi-public
 <Location /identity>
     SetHandler wsgi-script
diff --git a/files/apache-placement-api.template b/files/apache-placement-api.template
index b89ef96..011abb9 100644
--- a/files/apache-placement-api.template
+++ b/files/apache-placement-api.template
@@ -1,6 +1,8 @@
-Listen %PUBLICPORT%
-
-<VirtualHost *:%PUBLICPORT%>
+# NOTE(sbauza): This virtualhost is only here because some directives can
+# only be set by a virtualhost or server context, so that's why the port is not bound.
+# TODO(sbauza): Find a better way to identify a free port that is not corresponding to an existing
+# vhost.
+<VirtualHost *:8780>
     WSGIDaemonProcess placement-api processes=%APIWORKERS% threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
     WSGIProcessGroup placement-api
     WSGIScriptAlias / %PUBLICWSGI%
diff --git a/files/debs/general b/files/debs/general
index a1f2a4b..c121770 100644
--- a/files/debs/general
+++ b/files/debs/general
@@ -2,6 +2,7 @@
 bridge-utils
 bsdmainutils
 curl
+default-jre-headless  # NOPRIME
 g++
 gcc
 gettext  # used for compiling message catalogs
@@ -17,7 +18,6 @@
 libxslt1-dev  # lxml
 libyaml-dev
 lsof # useful when debugging
-openjdk-7-jre-headless  # NOPRIME
 openssh-server
 openssl
 pkg-config
diff --git a/files/debs/heat b/files/debs/heat
deleted file mode 100644
index 1ecbc78..0000000
--- a/files/debs/heat
+++ /dev/null
@@ -1 +0,0 @@
-gettext # dist:trusty
diff --git a/files/rpms-suse/general b/files/rpms-suse/general
index 3b19071..1044c25 100644
--- a/files/rpms-suse/general
+++ b/files/rpms-suse/general
@@ -21,6 +21,7 @@
 psmisc
 python-cmd2 # dist:opensuse-12.3
 python-devel  # pyOpenSSL
+python-xml
 screen
 tar
 tcpdump
diff --git a/functions b/functions
index 6a0ac67..0be9794 100644
--- a/functions
+++ b/functions
@@ -658,7 +658,7 @@
     # Enable bridge firewalling in case it's disabled in kernel (upstream
     # default is enabled, but some distributions may decide to change it).
     # This is at least needed for RHEL 7.2 and earlier releases.
-    for proto in arp ip ip6; do
+    for proto in ip ip6; do
         sudo sysctl -w net.bridge.bridge-nf-call-${proto}tables=1
     done
 }
diff --git a/functions-common b/functions-common
index cc1d42b..8d32bb4 100644
--- a/functions-common
+++ b/functions-common
@@ -87,7 +87,7 @@
         CA_CERT_ARG="--os-cacert $SSL_BUNDLE_FILE"
     fi
     # demo -> devstack
-    $TOP_DIR/tools/update_clouds_yaml.py \
+    $PYTHON $TOP_DIR/tools/update_clouds_yaml.py \
         --file $CLOUDS_YAML \
         --os-cloud devstack \
         --os-region-name $REGION_NAME \
@@ -99,7 +99,7 @@
         --os-project-name demo
 
     # alt_demo -> devstack-alt
-    $TOP_DIR/tools/update_clouds_yaml.py \
+    $PYTHON $TOP_DIR/tools/update_clouds_yaml.py \
         --file $CLOUDS_YAML \
         --os-cloud devstack-alt \
         --os-region-name $REGION_NAME \
@@ -111,7 +111,7 @@
         --os-project-name alt_demo
 
     # admin -> devstack-admin
-    $TOP_DIR/tools/update_clouds_yaml.py \
+    $PYTHON $TOP_DIR/tools/update_clouds_yaml.py \
         --file $CLOUDS_YAML \
         --os-cloud devstack-admin \
         --os-region-name $REGION_NAME \
@@ -216,7 +216,7 @@
 function deprecated {
     local text=$1
     DEPRECATED_TEXT+="\n$text"
-    echo "WARNING: $text"
+    echo "WARNING: $text" >&2
 }
 
 # Prints line number and "message" in error format
@@ -1678,7 +1678,7 @@
     local logfile=$2
 
     if [[ "$USE_SCREEN" = "True" ]]; then
-        screen_process "$name" "sudo tail -f $logfile | sed 's/\\\\\\\\x1b/\o033/g'"
+        screen_process "$name" "sudo tail -f $logfile | sed -u 's/\\\\\\\\x1b/\o033/g'"
     fi
 }
 
diff --git a/inc/meta-config b/inc/meta-config
index 6252135..be73b60 100644
--- a/inc/meta-config
+++ b/inc/meta-config
@@ -181,7 +181,8 @@
 
             realconfigfile=$(eval "echo $configfile")
             if [[ -z $realconfigfile ]]; then
-                die $LINENO "bogus config file specification: $configfile is undefined"
+                warn $LINENO "unknown config file specification: $configfile is undefined"
+                break
             fi
             dir=$(dirname $realconfigfile)
             if [[ -d $dir ]]; then
diff --git a/inc/python b/inc/python
index e4cfab8..04cde34 100644
--- a/inc/python
+++ b/inc/python
@@ -69,6 +69,20 @@
     pip_install $clean_name
 }
 
+# Wrapper for ``pip install`` that only installs versions of libraries
+# from the global-requirements specification with extras.
+#
+# Uses globals ``REQUIREMENTS_DIR``
+#
+# pip_install_gr_extras packagename extra1,extra2,...
+function pip_install_gr_extras {
+    local name=$1
+    local extras=$2
+    local clean_name
+    clean_name=$(get_from_global_requirements $name)
+    pip_install $clean_name[$extras]
+}
+
 # Determine the python versions supported by a package
 function get_python_versions_for_package {
     local name=$1
@@ -76,6 +90,27 @@
         | grep 'Language' | cut -f5 -d: | grep '\.' | tr '\n' ' '
 }
 
+# Check for python3 classifier in local directory
+function check_python3_support_for_package_local {
+    local name=$1
+    cd $name
+    set +e
+    classifier=$(python setup.py --classifiers \
+        | grep 'Programming Language :: Python :: 3$')
+    set -e
+    echo $classifier
+}
+
+# Check for python3 classifier on pypi
+function check_python3_support_for_package_remote {
+    local name=$1
+    set +e
+    classifier=$(curl -s -L "https://pypi.python.org/pypi/$name/json" \
+        | grep '"Programming Language :: Python :: 3"')
+    set -e
+    echo $classifier
+}
+
 # Wrapper for ``pip install`` to set cache and proxy environment variables
 # Uses globals ``OFFLINE``, ``PIP_VIRTUAL_ENV``,
 # ``PIP_UPGRADE``, ``TRACK_DEPENDS``, ``*_proxy``,
@@ -123,9 +158,41 @@
                 # default pip
                 local package_dir=${!#}
                 local python_versions
-                if [[ -d "$package_dir" ]]; then
+
+                # Special case some services that have experimental
+                # support for python3 in progress, but don't claim support
+                # in their classifier
+                echo "Check python version for : $package_dir"
+                if [[ ${package_dir##*/} == "nova" || ${package_dir##*/} == "glance" || \
+                        ${package_dir##*/} == "cinder" || ${package_dir##*/} == "swift" || \
+                        ${package_dir##*/} == "uwsgi" ]]; then
+                    echo "Using $PYTHON3_VERSION version to install $package_dir"
+                    sudo_pip="$sudo_pip LC_ALL=en_US.UTF-8"
+                    cmd_pip=$(get_pip_command $PYTHON3_VERSION)
+                elif [[ -d "$package_dir" ]]; then
                     python_versions=$(get_python_versions_for_package $package_dir)
                     if [[ $python_versions =~ $PYTHON3_VERSION ]]; then
+                        echo "Using $PYTHON3_VERSION version to install $package_dir"
+                        sudo_pip="$sudo_pip LC_ALL=en_US.UTF-8"
+                        cmd_pip=$(get_pip_command $PYTHON3_VERSION)
+                    else
+                        # The package may not have yet advertised python3.5
+                        # support so check for just python3 classifier and log
+                        # a warning.
+                        python3_classifier=$(check_python3_support_for_package_local $package_dir)
+                        if [[ ! -z "$python3_classifier" ]]; then
+                            echo "Using $PYTHON3_VERSION version to install $package_dir"
+                            sudo_pip="$sudo_pip LC_ALL=en_US.UTF-8"
+                            cmd_pip=$(get_pip_command $PYTHON3_VERSION)
+                        fi
+                    fi
+                else
+                    # Check pypi as we don't have the package on disk
+                    package=$(echo $package_dir | grep -o '^[.a-zA-Z0-9_-]*')
+                    python3_classifier=$(check_python3_support_for_package_remote $package)
+                    if [[ ! -z "$python3_classifier" ]]; then
+                        echo "Using $PYTHON3_VERSION version to install $package"
+                        sudo_pip="$sudo_pip LC_ALL=en_US.UTF-8"
                         cmd_pip=$(get_pip_command $PYTHON3_VERSION)
                     fi
                 fi
diff --git a/lib/apache b/lib/apache
index 2dc626f..d1a11ae 100644
--- a/lib/apache
+++ b/lib/apache
@@ -71,7 +71,15 @@
     # Apache installation, because we mark it NOPRIME
     if is_ubuntu; then
         # Install apache2, which is NOPRIME'd
-        install_package apache2 libapache2-mod-wsgi
+        install_package apache2
+        if python3_enabled; then
+            if is_package_installed libapache2-mod-wsgi; then
+                uninstall_package libapache2-mod-wsgi
+            fi
+            install_package libapache2-mod-wsgi-py3
+        else
+            install_package libapache2-mod-wsgi
+        fi
     elif is_fedora; then
         sudo rm -f /etc/httpd/conf.d/000-*
         install_package httpd mod_wsgi
diff --git a/lib/cinder b/lib/cinder
index f6ad780..40f0f16 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -373,6 +373,13 @@
     iniset $CINDER_CONF DEFAULT os_privileged_user_password "$SERVICE_PASSWORD"
     iniset $CINDER_CONF DEFAULT os_privileged_user_tenant "$SERVICE_PROJECT_NAME"
     iniset $CINDER_CONF DEFAULT graceful_shutdown_timeout "$SERVICE_GRACEFUL_SHUTDOWN_TIMEOUT"
+
+    # Set the backend url according to the configured dlm backend
+    if is_dlm_enabled; then
+        if [[ "$(dlm_backend)" == "zookeeper" ]]; then
+            iniset $CINDER_CONF coordination backend_url "zookeeper://${SERVICE_HOST}:2181"
+        fi
+    fi
 }
 
 # create_cinder_accounts() - Set up common required cinder accounts
diff --git a/lib/databases/mysql b/lib/databases/mysql
index f6cc922..89ae082 100644
--- a/lib/databases/mysql
+++ b/lib/databases/mysql
@@ -82,10 +82,9 @@
     fi
 
     # Set the root password - only works the first time. For Ubuntu, we already
-    # did that with debconf before installing the package.
-    if ! is_ubuntu; then
-        sudo mysqladmin -u root password $DATABASE_PASSWORD || true
-    fi
+    # did that with debconf before installing the package, but we still try,
+    # because the package might have been installed already.
+    sudo mysqladmin -u root password $DATABASE_PASSWORD || true
 
     # Update the DB to give user '$DATABASE_USER'@'%' full control of the all databases:
     sudo mysql -uroot -p$DATABASE_PASSWORD -h127.0.0.1 -e "GRANT ALL PRIVILEGES ON *.* TO '$DATABASE_USER'@'%' identified by '$DATABASE_PASSWORD';"
diff --git a/lib/databases/postgresql b/lib/databases/postgresql
index 14425a5..1f347f5 100644
--- a/lib/databases/postgresql
+++ b/lib/databases/postgresql
@@ -47,7 +47,7 @@
 }
 
 function configure_database_postgresql {
-    local pg_conf pg_dir pg_hba root_roles version
+    local pg_conf pg_dir pg_hba check_role version
     echo_summary "Configuring and starting PostgreSQL"
     if is_fedora; then
         pg_hba=/var/lib/pgsql/data/pg_hba.conf
@@ -85,8 +85,8 @@
     restart_service postgresql
 
     # Create the role if it's not here or else alter it.
-    root_roles=$(sudo -u root sudo -u postgres -i psql -t -c "SELECT 'HERE' from pg_roles where rolname='root'")
-    if [[ ${root_roles} == *HERE ]];then
+    check_role=$(sudo -u root sudo -u postgres -i psql -t -c "SELECT 'HERE' from pg_roles where rolname='$DATABASE_USER'")
+    if [[ ${check_role} == *HERE ]];then
         sudo -u root sudo -u postgres -i psql -c "ALTER ROLE $DATABASE_USER WITH SUPERUSER LOGIN PASSWORD '$DATABASE_PASSWORD'"
     else
         sudo -u root sudo -u postgres -i psql -c "CREATE ROLE $DATABASE_USER WITH SUPERUSER LOGIN PASSWORD '$DATABASE_PASSWORD'"
diff --git a/lib/dlm b/lib/dlm
index e391535..b5ac0f5 100644
--- a/lib/dlm
+++ b/lib/dlm
@@ -91,6 +91,7 @@
 # install_dlm() - Collect source and prepare
 function install_dlm {
     if is_dlm_enabled; then
+        pip_install_gr_extras tooz zookeeper
         if is_ubuntu; then
             install_package zookeeperd
         elif is_fedora; then
diff --git a/lib/glance b/lib/glance
index da9cd43..4ba1d20 100644
--- a/lib/glance
+++ b/lib/glance
@@ -161,6 +161,9 @@
     if is_service_enabled s-proxy; then
         iniset $GLANCE_API_CONF glance_store default_store swift
         iniset $GLANCE_API_CONF glance_store swift_store_create_container_on_put True
+        if python3_enabled; then
+            iniset $GLANCE_API_CONF glance_store swift_store_auth_insecure True
+        fi
 
         iniset $GLANCE_API_CONF glance_store swift_store_config_file $GLANCE_SWIFT_STORE_CONF
         iniset $GLANCE_API_CONF glance_store default_swift_reference ref1
@@ -186,7 +189,13 @@
         fi
 
         iniset $GLANCE_SWIFT_STORE_CONF ref1 key $SERVICE_PASSWORD
-        iniset $GLANCE_SWIFT_STORE_CONF ref1 auth_address $KEYSTONE_SERVICE_URI/v3
+        if python3_enabled; then
+            # NOTE(dims): Currently the glance_store+swift does not support either an insecure flag
+            # or ability to specify the CACERT. So fallback to http:// url
+            iniset $GLANCE_SWIFT_STORE_CONF ref1 auth_address ${KEYSTONE_SERVICE_URI/https/http}/v3
+        else
+            iniset $GLANCE_SWIFT_STORE_CONF ref1 auth_address $KEYSTONE_SERVICE_URI/v3
+        fi
         iniset $GLANCE_SWIFT_STORE_CONF ref1 auth_version 3
 
         # commenting is not strictly necessary but it's confusing to have bad values in conf
diff --git a/lib/heat b/lib/heat
deleted file mode 100644
index 0863128..0000000
--- a/lib/heat
+++ /dev/null
@@ -1,467 +0,0 @@
-#!/bin/bash
-#
-# lib/heat
-# Install and start **Heat** service
-
-# To enable, add the following to localrc
-#
-#   ENABLED_SERVICES+=,heat,h-api,h-api-cfn,h-api-cw,h-eng
-
-# Dependencies:
-# (none)
-
-# stack.sh
-# ---------
-# - install_heatclient
-# - install_heat
-# - configure_heatclient
-# - configure_heat
-# - _config_heat_apache_wsgi
-# - init_heat
-# - start_heat
-# - stop_heat
-# - cleanup_heat
-
-# Save trace setting
-_XTRACE_HEAT=$(set +o | grep xtrace)
-set +o xtrace
-
-
-# Defaults
-# --------
-
-# set up default directories
-GITDIR["python-heatclient"]=$DEST/python-heatclient
-
-# Toggle for deploying Heat-API under HTTPD + mod_wsgi
-HEAT_USE_MOD_WSGI=${HEAT_USE_MOD_WSGI:-False}
-
-HEAT_DIR=$DEST/heat
-HEAT_CFNTOOLS_DIR=$DEST/heat-cfntools
-HEAT_TEMPLATES_REPO_DIR=$DEST/heat-templates
-OCC_DIR=$DEST/os-collect-config
-ORC_DIR=$DEST/os-refresh-config
-OAC_DIR=$DEST/os-apply-config
-
-HEAT_PIP_REPO=$DATA_DIR/heat-pip-repo
-HEAT_PIP_REPO_PORT=${HEAT_PIP_REPO_PORT:-8899}
-
-HEAT_AUTH_CACHE_DIR=${HEAT_AUTH_CACHE_DIR:-/var/cache/heat}
-HEAT_STANDALONE=$(trueorfalse False HEAT_STANDALONE)
-HEAT_ENABLE_ADOPT_ABANDON=$(trueorfalse False HEAT_ENABLE_ADOPT_ABANDON)
-HEAT_CONF_DIR=/etc/heat
-HEAT_CONF=$HEAT_CONF_DIR/heat.conf
-HEAT_ENV_DIR=$HEAT_CONF_DIR/environment.d
-HEAT_TEMPLATES_DIR=$HEAT_CONF_DIR/templates
-HEAT_API_HOST=${HEAT_API_HOST:-$HOST_IP}
-HEAT_API_PORT=${HEAT_API_PORT:-8004}
-HEAT_SERVICE_USER=${HEAT_SERVICE_USER:-heat}
-HEAT_TRUSTEE_USER=${HEAT_TRUSTEE_USER:-$HEAT_SERVICE_USER}
-HEAT_TRUSTEE_PASSWORD=${HEAT_TRUSTEE_PASSWORD:-$SERVICE_PASSWORD}
-HEAT_TRUSTEE_DOMAIN=${HEAT_TRUSTEE_DOMAIN:-default}
-
-# Support entry points installation of console scripts
-HEAT_BIN_DIR=$(get_python_exec_prefix)
-
-# other default options
-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}
-    if [[ ${HEAT_DEFERRED_AUTH} != "password" ]]; then
-        # Heat does not support keystone trusts when deployed in
-        # standalone mode
-        die $LINENO \
-            'HEAT_DEFERRED_AUTH can only be set to "password" when HEAT_STANDALONE is True.'
-    fi
-else
-    HEAT_STACK_DOMAIN=$(trueorfalse True HEAT_STACK_DOMAIN)
-    HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-}
-fi
-HEAT_PLUGIN_DIR=${HEAT_PLUGIN_DIR:-$DATA_DIR/heat/plugins}
-ENABLE_HEAT_PLUGINS=${ENABLE_HEAT_PLUGINS:-}
-
-# Functions
-# ---------
-
-# Test if any Heat services are enabled
-# is_heat_enabled
-function is_heat_enabled {
-    [[ ,${ENABLED_SERVICES} =~ ,"h-" ]] && return 0
-    return 1
-}
-
-# cleanup_heat() - Remove residual data files, anything left over from previous
-# runs that a clean run would need to clean up
-function cleanup_heat {
-    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 {
-
-    sudo install -d -o $STACK_USER $HEAT_CONF_DIR
-    # remove old config files
-    rm -f $HEAT_CONF_DIR/heat-*.conf
-
-    HEAT_API_CFN_HOST=${HEAT_API_CFN_HOST:-$HOST_IP}
-    HEAT_API_CFN_PORT=${HEAT_API_CFN_PORT:-8000}
-    HEAT_ENGINE_HOST=${HEAT_ENGINE_HOST:-$SERVICE_HOST}
-    HEAT_ENGINE_PORT=${HEAT_ENGINE_PORT:-8001}
-    HEAT_API_CW_HOST=${HEAT_API_CW_HOST:-$HOST_IP}
-    HEAT_API_CW_PORT=${HEAT_API_CW_PORT:-8003}
-    HEAT_API_PASTE_FILE=$HEAT_CONF_DIR/api-paste.ini
-    HEAT_POLICY_FILE=$HEAT_CONF_DIR/policy.json
-
-    cp $HEAT_DIR/etc/heat/api-paste.ini $HEAT_API_PASTE_FILE
-    cp $HEAT_DIR/etc/heat/policy.json $HEAT_POLICY_FILE
-
-    # common options
-    iniset_rpc_backend heat $HEAT_CONF
-    iniset $HEAT_CONF DEFAULT heat_metadata_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT
-    iniset $HEAT_CONF DEFAULT heat_waitcondition_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1/waitcondition
-    iniset $HEAT_CONF DEFAULT heat_watch_server_url http://$HEAT_API_CW_HOST:$HEAT_API_CW_PORT
-    iniset $HEAT_CONF database connection `database_connection_url heat`
-    iniset $HEAT_CONF DEFAULT auth_encryption_key $(generate_hex_string 16)
-
-    iniset $HEAT_CONF DEFAULT region_name_for_services "$REGION_NAME"
-
-    # logging
-    iniset $HEAT_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
-    iniset $HEAT_CONF DEFAULT use_syslog $SYSLOG
-    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ] && [ "$HEAT_USE_MOD_WSGI" == "False" ]  ; then
-        # Add color to logging output
-        setup_colorized_logging $HEAT_CONF DEFAULT tenant user
-    fi
-
-    if [ ! -z "$HEAT_DEFERRED_AUTH" ]; then
-        iniset $HEAT_CONF DEFAULT deferred_auth_method $HEAT_DEFERRED_AUTH
-    fi
-
-    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
-        _config_heat_apache_wsgi
-    fi
-
-    if [[ "$HEAT_STANDALONE" = "True" ]]; then
-        iniset $HEAT_CONF paste_deploy flavor standalone
-        iniset $HEAT_CONF clients_heat url "http://$HEAT_API_HOST:$HEAT_API_PORT/v1/%(tenant_id)s"
-    else
-        configure_auth_token_middleware $HEAT_CONF heat $HEAT_AUTH_CACHE_DIR
-    fi
-
-    # If HEAT_DEFERRED_AUTH is unset or explicitly set to trusts, configure
-    # the section for the client plugin associated with the trustee
-    if [ -z "$HEAT_DEFERRED_AUTH" -o "trusts" == "$HEAT_DEFERRED_AUTH" ]; then
-        iniset $HEAT_CONF trustee auth_type password
-        iniset $HEAT_CONF trustee auth_url $KEYSTONE_AUTH_URI
-        iniset $HEAT_CONF trustee username $HEAT_TRUSTEE_USER
-        iniset $HEAT_CONF trustee password $HEAT_TRUSTEE_PASSWORD
-        iniset $HEAT_CONF trustee user_domain_id $HEAT_TRUSTEE_DOMAIN
-    fi
-
-    # clients_keystone
-    iniset $HEAT_CONF clients_keystone auth_uri $KEYSTONE_AUTH_URI
-
-    # OpenStack API
-    iniset $HEAT_CONF heat_api bind_port $HEAT_API_PORT
-    iniset $HEAT_CONF heat_api workers "$API_WORKERS"
-
-    # Cloudformation API
-    iniset $HEAT_CONF heat_api_cfn bind_port $HEAT_API_CFN_PORT
-
-    # Cloudwatch API
-    iniset $HEAT_CONF heat_api_cloudwatch bind_port $HEAT_API_CW_PORT
-
-    if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
-        iniset $HEAT_CONF clients_keystone ca_file $SSL_BUNDLE_FILE
-    fi
-
-    if is_ssl_enabled_service "nova" || is_service_enabled tls-proxy; then
-        iniset $HEAT_CONF clients_nova ca_file $SSL_BUNDLE_FILE
-    fi
-
-    if is_ssl_enabled_service "cinder" || is_service_enabled tls-proxy; then
-        iniset $HEAT_CONF clients_cinder ca_file $SSL_BUNDLE_FILE
-    fi
-
-    if [[ "$HEAT_ENABLE_ADOPT_ABANDON" = "True" ]]; then
-        iniset $HEAT_CONF DEFAULT enable_stack_adopt true
-        iniset $HEAT_CONF DEFAULT enable_stack_abandon true
-    fi
-
-    iniset $HEAT_CONF cache enabled "True"
-    iniset $HEAT_CONF cache backend "dogpile.cache.memory"
-
-    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/
-
-    # copy the default templates
-    cp $HEAT_DIR/etc/heat/templates/* $HEAT_TEMPLATES_DIR/
-
-    # Enable heat plugins.
-    # NOTE(nic): The symlink nonsense is necessary because when
-    # plugins are installed in "developer mode", the final component
-    # of their target directory is always "resources", which confuses
-    # Heat's plugin loader into believing that all plugins are named
-    # "resources", and therefore are all the same plugin; so it
-    # will only load one of them.  Linking them all to a common
-    # location with unique names avoids that type of collision,
-    # while still allowing the plugins to be edited in-tree.
-    local err_count=0
-
-    if [ -n "$ENABLE_HEAT_PLUGINS" ]; then
-        mkdir -p $HEAT_PLUGIN_DIR
-        # Clean up cruft from any previous runs
-        rm -f $HEAT_PLUGIN_DIR/*
-        iniset $HEAT_CONF DEFAULT plugin_dirs $HEAT_PLUGIN_DIR
-    fi
-
-    for heat_plugin in $ENABLE_HEAT_PLUGINS; do
-        if [ -d $HEAT_DIR/contrib/$heat_plugin ]; then
-            setup_package $HEAT_DIR/contrib/$heat_plugin -e
-            ln -s $HEAT_DIR/contrib/$heat_plugin/$heat_plugin/resources $HEAT_PLUGIN_DIR/$heat_plugin
-        else
-            : # clear retval on the test so that we can roll up errors
-            err $LINENO "Requested Heat plugin(${heat_plugin}) not found."
-            err_count=$(($err_count + 1))
-        fi
-    done
-    [ $err_count -eq 0 ] || die $LINENO "$err_count of the requested Heat plugins could not be installed."
-}
-
-# init_heat() - Initialize database
-function init_heat {
-
-    # (re)create heat database
-    recreate_database heat
-
-    $HEAT_BIN_DIR/heat-manage --config-file $HEAT_CONF db_sync
-    create_heat_cache_dir
-}
-
-# create_heat_cache_dir() - Part of the init_heat() process
-function create_heat_cache_dir {
-    # Create cache dirs
-    sudo install -d -o $STACK_USER $HEAT_AUTH_CACHE_DIR
-}
-
-# install_heatclient() - Collect source and prepare
-function install_heatclient {
-    if use_library_from_git "python-heatclient"; then
-        git_clone_by_name "python-heatclient"
-        setup_dev_lib "python-heatclient"
-        sudo install -D -m 0644 -o $STACK_USER {${GITDIR["python-heatclient"]}/tools/,/etc/bash_completion.d/}heat.bash_completion
-    fi
-}
-
-# install_heat() - Collect source and prepare
-function install_heat {
-    git_clone $HEAT_REPO $HEAT_DIR $HEAT_BRANCH
-    setup_develop $HEAT_DIR
-    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
-        install_apache_wsgi
-    fi
-}
-
-# install_heat_other() - Collect source and prepare
-function install_heat_other {
-    git_clone $HEAT_CFNTOOLS_REPO $HEAT_CFNTOOLS_DIR $HEAT_CFNTOOLS_BRANCH
-    git_clone $HEAT_TEMPLATES_REPO $HEAT_TEMPLATES_REPO_DIR $HEAT_TEMPLATES_BRANCH
-    git_clone $OAC_REPO $OAC_DIR $OAC_BRANCH
-    git_clone $OCC_REPO $OCC_DIR $OCC_BRANCH
-    git_clone $ORC_REPO $ORC_DIR $ORC_BRANCH
-}
-
-# start_heat() - Start running processes, including screen
-function start_heat {
-    run_process h-eng "$HEAT_BIN_DIR/heat-engine --config-file=$HEAT_CONF"
-
-    # If the site is not enabled then we are in a grenade scenario
-    local enabled_site_file
-    enabled_site_file=$(apache_site_config_for heat-api)
-    if [ -f ${enabled_site_file} ] && [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
-        enable_apache_site heat-api
-        enable_apache_site heat-api-cfn
-        enable_apache_site heat-api-cloudwatch
-        restart_apache_server
-        tail_log heat-api /var/log/$APACHE_NAME/heat-api.log
-        tail_log heat-api-cfn /var/log/$APACHE_NAME/heat-api-cfn.log
-        tail_log heat-api-cloudwatch /var/log/$APACHE_NAME/heat-api-cloudwatch.log
-    else
-        run_process h-api "$HEAT_BIN_DIR/heat-api --config-file=$HEAT_CONF"
-        run_process h-api-cfn "$HEAT_BIN_DIR/heat-api-cfn --config-file=$HEAT_CONF"
-        run_process h-api-cw "$HEAT_BIN_DIR/heat-api-cloudwatch --config-file=$HEAT_CONF"
-    fi
-}
-
-# stop_heat() - Stop running processes
-function stop_heat {
-    # Kill the screen windows
-    stop_process h-eng
-
-    if [ "$HEAT_USE_MOD_WSGI" == "True" ]; then
-        disable_apache_site heat-api
-        disable_apache_site heat-api-cfn
-        disable_apache_site heat-api-cloudwatch
-        restart_apache_server
-    else
-        local serv
-        for serv in h-api h-api-cfn h-api-cw; do
-            stop_process $serv
-        done
-    fi
-
-}
-
-# _cleanup_heat_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
-function _cleanup_heat_apache_wsgi {
-    sudo rm -f $(apache_site_config_for heat-api)
-    sudo rm -f $(apache_site_config_for heat-api-cfn)
-    sudo rm -f $(apache_site_config_for heat-api-cloudwatch)
-}
-
-# _config_heat_apache_wsgi() - Set WSGI config files of Heat
-function _config_heat_apache_wsgi {
-
-    local heat_apache_conf
-    heat_apache_conf=$(apache_site_config_for heat-api)
-    local heat_cfn_apache_conf
-    heat_cfn_apache_conf=$(apache_site_config_for heat-api-cfn)
-    local heat_cloudwatch_apache_conf
-    heat_cloudwatch_apache_conf=$(apache_site_config_for heat-api-cloudwatch)
-    local heat_ssl=""
-    local heat_certfile=""
-    local heat_keyfile=""
-    local heat_api_port=$HEAT_API_PORT
-    local heat_cfn_api_port=$HEAT_API_CFN_PORT
-    local heat_cw_api_port=$HEAT_API_CW_PORT
-    local venv_path=""
-
-    sudo cp $FILES/apache-heat-api.template $heat_apache_conf
-    sudo sed -e "
-        s|%PUBLICPORT%|$heat_api_port|g;
-        s|%APACHE_NAME%|$APACHE_NAME|g;
-        s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
-        s|%SSLENGINE%|$heat_ssl|g;
-        s|%SSLCERTFILE%|$heat_certfile|g;
-        s|%SSLKEYFILE%|$heat_keyfile|g;
-        s|%USER%|$STACK_USER|g;
-        s|%VIRTUALENV%|$venv_path|g
-    " -i $heat_apache_conf
-
-    sudo cp $FILES/apache-heat-api-cfn.template $heat_cfn_apache_conf
-    sudo sed -e "
-        s|%PUBLICPORT%|$heat_cfn_api_port|g;
-        s|%APACHE_NAME%|$APACHE_NAME|g;
-        s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
-        s|%SSLENGINE%|$heat_ssl|g;
-        s|%SSLCERTFILE%|$heat_certfile|g;
-        s|%SSLKEYFILE%|$heat_keyfile|g;
-        s|%USER%|$STACK_USER|g;
-        s|%VIRTUALENV%|$venv_path|g
-    " -i $heat_cfn_apache_conf
-
-    sudo cp $FILES/apache-heat-api-cloudwatch.template $heat_cloudwatch_apache_conf
-    sudo sed -e "
-        s|%PUBLICPORT%|$heat_cw_api_port|g;
-        s|%APACHE_NAME%|$APACHE_NAME|g;
-        s|%HEAT_BIN_DIR%|$HEAT_BIN_DIR|g;
-        s|%SSLENGINE%|$heat_ssl|g;
-        s|%SSLCERTFILE%|$heat_certfile|g;
-        s|%SSLKEYFILE%|$heat_keyfile|g;
-        s|%USER%|$STACK_USER|g;
-        s|%VIRTUALENV%|$venv_path|g
-    " -i $heat_cloudwatch_apache_conf
-}
-
-
-# create_heat_accounts() - Set up common required heat accounts
-function create_heat_accounts {
-    if [[ "$HEAT_STANDALONE" != "True" ]]; then
-
-        create_service_user "heat" "admin"
-        get_or_create_service "heat" "orchestration" "Heat Orchestration Service"
-        get_or_create_endpoint \
-            "orchestration" \
-            "$REGION_NAME" \
-            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(project_id)s" \
-            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(project_id)s" \
-            "$SERVICE_PROTOCOL://$HEAT_API_HOST:$HEAT_API_PORT/v1/\$(project_id)s"
-
-        get_or_create_service "heat-cfn" "cloudformation" "Heat CloudFormation Service"
-        get_or_create_endpoint \
-            "cloudformation"  \
-            "$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"
-
-        # heat_stack_user role is for users created by Heat
-        get_or_create_role "heat_stack_user"
-    fi
-
-    if [[ "$HEAT_STACK_DOMAIN" == "True" ]]; then
-        # domain -> heat and user -> heat_domain_admin
-        domain_id=$(get_or_create_domain heat 'Owns users and projects created by heat')
-        iniset $HEAT_CONF DEFAULT stack_user_domain_id ${domain_id}
-        get_or_create_user heat_domain_admin $SERVICE_PASSWORD heat
-        get_or_add_user_domain_role admin heat_domain_admin heat
-        iniset $HEAT_CONF DEFAULT stack_domain_admin heat_domain_admin
-        iniset $HEAT_CONF DEFAULT stack_domain_admin_password $SERVICE_PASSWORD
-    fi
-}
-
-# build_heat_pip_mirror() - Build a pip mirror containing heat agent projects
-function build_heat_pip_mirror {
-    local project_dirs="$OCC_DIR $OAC_DIR $ORC_DIR $HEAT_CFNTOOLS_DIR"
-    local projpath proj package
-
-    rm -rf $HEAT_PIP_REPO
-    mkdir -p $HEAT_PIP_REPO
-
-    echo "<html><body>" > $HEAT_PIP_REPO/index.html
-    for projpath in $project_dirs; do
-        proj=$(basename $projpath)
-        mkdir -p $HEAT_PIP_REPO/$proj
-        pushd $projpath
-        rm -rf dist
-        python setup.py sdist
-        pushd dist
-        package=$(ls *)
-        mv $package $HEAT_PIP_REPO/$proj/$package
-        popd
-
-        echo "<html><body><a href=\"$package\">$package</a></body></html>" > $HEAT_PIP_REPO/$proj/index.html
-        echo "<a href=\"$proj\">$proj</a><br/>" >> $HEAT_PIP_REPO/index.html
-
-        popd
-    done
-
-    echo "</body></html>" >> $HEAT_PIP_REPO/index.html
-
-    local heat_pip_repo_apache_conf
-    heat_pip_repo_apache_conf=$(apache_site_config_for heat_pip_repo)
-
-    sudo cp $FILES/apache-heat-pip-repo.template $heat_pip_repo_apache_conf
-    sudo sed -e "
-        s|%HEAT_PIP_REPO%|$HEAT_PIP_REPO|g;
-        s|%HEAT_PIP_REPO_PORT%|$HEAT_PIP_REPO_PORT|g;
-        s|%APACHE_NAME%|$APACHE_NAME|g;
-    " -i $heat_pip_repo_apache_conf
-    enable_apache_site heat_pip_repo
-    restart_apache_server
-    sudo iptables -I INPUT -d $HOST_IP -p tcp --dport $HEAT_PIP_REPO_PORT -j ACCEPT || true
-}
-
-# Restore xtrace
-$_XTRACE_HEAT
-
-# Tell emacs to use shell-script-mode
-## Local variables:
-## mode: shell-script
-## End:
diff --git a/lib/horizon b/lib/horizon
index 830da09..9c7ec00 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -81,7 +81,7 @@
     # Horizon is installed as develop mode, so we can compile here.
     # Message catalog compilation is handled by Django admin script,
     # so compiling them after the installation avoids Django installation twice.
-    (cd $HORIZON_DIR; python manage.py compilemessages)
+    (cd $HORIZON_DIR; $PYTHON manage.py compilemessages)
 
     # ``local_settings.py`` is used to override horizon default settings.
     local local_settings=$HORIZON_DIR/openstack_dashboard/local/local_settings.py
@@ -162,7 +162,7 @@
         git_clone_by_name "django_openstack_auth"
         # Compile message catalogs before installation
         _prepare_message_catalog_compilation
-        (cd $dir; python setup.py compile_catalog)
+        (cd $dir; $PYTHON setup.py compile_catalog)
         setup_dev_lib "django_openstack_auth"
     fi
     # if we aren't using this library from git, then we just let it
diff --git a/lib/keystone b/lib/keystone
index 948d5b4..34730b8 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -131,6 +131,12 @@
 KEYSTONE_AUTH_URI_V3=$KEYSTONE_AUTH_URI/v3
 KEYSTONE_SERVICE_URI_V3=$KEYSTONE_SERVICE_URI/v3
 
+# Security compliance
+KEYSTONE_SECURITY_COMPLIANCE_ENABLED=${KEYSTONE_SECURITY_COMPLIANCE_ENABLED:-True}
+KEYSTONE_LOCKOUT_FAILURE_ATTEMPTS=${KEYSTONE_LOCKOUT_FAILURE_ATTEMPTS:-2}
+KEYSTONE_LOCKOUT_DURATION=${KEYSTONE_LOCKOUT_DURATION:-5}
+KEYSTONE_UNIQUE_LAST_PASSWORD_COUNT=${KEYSTONE_UNIQUE_LAST_PASSWORD_COUNT:-2}
+
 
 # Functions
 # ---------
@@ -153,6 +159,7 @@
 function _config_keystone_apache_wsgi {
     local keystone_apache_conf
     keystone_apache_conf=$(apache_site_config_for keystone)
+    keystone_ssl_listen="#"
     local keystone_ssl=""
     local keystone_certfile=""
     local keystone_keyfile=""
@@ -161,6 +168,7 @@
     local venv_path=""
 
     if is_ssl_enabled_service key; then
+        keystone_ssl_listen=""
         keystone_ssl="SSLEngine On"
         keystone_certfile="SSLCertificateFile $KEYSTONE_SSL_CERT"
         keystone_keyfile="SSLCertificateKeyFile $KEYSTONE_SSL_KEY"
@@ -178,6 +186,7 @@
         s|%PUBLICPORT%|$keystone_service_port|g;
         s|%ADMINPORT%|$keystone_auth_port|g;
         s|%APACHE_NAME%|$APACHE_NAME|g;
+        s|%SSLLISTEN%|$keystone_ssl_listen|g;
         s|%SSLENGINE%|$keystone_ssl|g;
         s|%SSLCERTFILE%|$keystone_certfile|g;
         s|%SSLKEYFILE%|$keystone_keyfile|g;
@@ -336,6 +345,12 @@
     # 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_name admin
+
+    if [[ "$KEYSTONE_SECURITY_COMPLIANCE_ENABLED" = True ]]; then
+        iniset $KEYSTONE_CONF security_compliance lockout_failure_attempts $KEYSTONE_LOCKOUT_FAILURE_ATTEMPTS
+        iniset $KEYSTONE_CONF security_compliance lockout_duration $KEYSTONE_LOCKOUT_DURATION
+        iniset $KEYSTONE_CONF security_compliance unique_last_password_count $KEYSTONE_UNIQUE_LAST_PASSWORD_COUNT
+    fi
 }
 
 # create_keystone_accounts() - Sets up common required keystone accounts
@@ -442,14 +457,16 @@
 #
 # create_service_user <name> [role]
 #
-# The role defaults to the service role. It is allowed to be provided as optional as historically
+# We always add the service role, other roles are also allowed to be added as historically
 # a lot of projects have configured themselves with the admin or other role here if they are
 # using this user for other purposes beyond simply auth_token middleware.
 function create_service_user {
-    local role=${2:-service}
-
     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"
+    get_or_add_user_project_role service "$1" "$SERVICE_PROJECT_NAME" "$SERVICE_DOMAIN_NAME" "$SERVICE_DOMAIN_NAME"
+
+    if [[ -n "$2" ]]; then
+        get_or_add_user_project_role "$2" "$1" "$SERVICE_PROJECT_NAME" "$SERVICE_DOMAIN_NAME" "$SERVICE_DOMAIN_NAME"
+    fi
 }
 
 # Configure the service to use the auth token middleware.
@@ -485,8 +502,10 @@
         init_ldap
     fi
 
-    # (Re)create keystone database
-    recreate_database keystone
+    if [[ "$RECREATE_KEYSTONE_DB" == True ]]; then
+        # (Re)create keystone database
+        recreate_database keystone
+    fi
 
     # Initialize keystone database
     $KEYSTONE_BIN_DIR/keystone-manage --config-file $KEYSTONE_CONF db_sync
diff --git a/lib/lvm b/lib/lvm
index 99c7ba9..0cebd92 100644
--- a/lib/lvm
+++ b/lib/lvm
@@ -101,7 +101,7 @@
 # init_lvm_volume_group() initializes the volume group creating the backing
 # file if necessary
 #
-# Usage: init_lvm_volume_group() $vg
+# Usage: init_lvm_volume_group() $vg $size
 function init_lvm_volume_group {
     local vg=$1
     local size=$2
diff --git a/lib/neutron b/lib/neutron
index d30e185..f6c705c 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -73,6 +73,9 @@
 # Add all enabled config files to a single config arg
 NEUTRON_CONFIG_ARG=${NEUTRON_CONFIG_ARG:-""}
 
+# Additional neutron api config files
+declare -a _NEUTRON_SERVER_EXTRA_CONF_FILES_ABS
+
 # Functions
 # ---------
 
@@ -90,6 +93,10 @@
     return 1
 }
 
+if is_neutron_legacy_enabled; then
+    source $TOP_DIR/lib/neutron-legacy
+fi
+
 # 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 {
@@ -159,9 +166,9 @@
         # Configure VXLAN
         # TODO(sc68cal) not hardcode?
         iniset $NEUTRON_CORE_PLUGIN_CONF ml2 tenant_network_types vxlan
-        iniset $NEUTRON_CORE_PLUGIN_CONF ml2 type_drivers vxlan
         iniset $NEUTRON_CORE_PLUGIN_CONF ml2 mechanism_drivers openvswitch,linuxbridge
         iniset $NEUTRON_CORE_PLUGIN_CONF ml2_type_vxlan vni_ranges 1001:2000
+        iniset $NEUTRON_CORE_PLUGIN_CONF ml2_type_flat flat_networks public
         if [[ "$NEUTRON_PORT_SECURITY" = "True" ]]; then
             iniset $NEUTRON_CORE_PLUGIN_CONF ml2 extension_drivers port_security
         fi
@@ -174,10 +181,10 @@
 
         # Configure the neutron agent
         if [[ $NEUTRON_AGENT == "linuxbridge" ]]; then
-            iniset $NEUTRON_CORE_PLUGIN_CONF securitygroup iptables
+            iniset $NEUTRON_CORE_PLUGIN_CONF securitygroup firewall_driver iptables
             iniset $NEUTRON_CORE_PLUGIN_CONF vxlan local_ip $HOST_IP
         else
-            iniset $NEUTRON_CORE_PLUGIN_CONF securitygroup iptables_hybrid
+            iniset $NEUTRON_CORE_PLUGIN_CONF securitygroup firewall_driver iptables_hybrid
             iniset $NEUTRON_CORE_PLUGIN_CONF ovs local_ip $HOST_IP
         fi
 
@@ -389,9 +396,17 @@
         service_protocol="http"
     fi
 
+    local opts = ""
+    opts+="--config-file $NEUTRON_CONF"
+    opts+="--config-file $NEUTRON_CORE_PLUGIN_CONF"
+    local cfg_file
+    for cfg_file in ${_NEUTRON_SERVER_EXTRA_CONF_FILES_ABS[@]}; do
+        opts+=" --config-file $cfg_file"
+    done
+
     # 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_CORE_PLUGIN_CONF"
+    run_process neutron-api "$NEUTRON_BIN_DIR/neutron-server $ops"
 
     if is_ssl_enabled_service "neutron"; then
         ssl_ca="--ca-certificate=${SSL_BUNDLE_FILE}"
@@ -500,6 +515,10 @@
     iniset $NEUTRON_CONF DEFAULT service_plugins $plugins
 }
 
+function neutron_server_config_add_new {
+    _NEUTRON_SERVER_EXTRA_CONF_FILES_ABS+=($1)
+}
+
 # Dispatch functions
 # These are needed for compatibility between the old and new implementations
 # where there are function name overlaps.  These will be removed when
@@ -568,6 +587,24 @@
     fi
 }
 
+function install_neutron_agent_packages {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        install_neutron_agent_packages_mutnauq "$@"
+    else
+        :
+    fi
+}
+
+function neutron_server_config_add {
+    if is_neutron_legacy_enabled; then
+        # Call back to old function
+        mutnauq_server_config_add "$@"
+    else
+        neutron_server_config_add_new "$@"
+    fi
+}
+
 function start_neutron {
     if is_neutron_legacy_enabled; then
         # Call back to old function
diff --git a/lib/neutron-legacy b/lib/neutron-legacy
index 0b0caf1..29c187e 100644
--- a/lib/neutron-legacy
+++ b/lib/neutron-legacy
@@ -128,10 +128,24 @@
 VIF_PLUGGING_IS_FATAL=${VIF_PLUGGING_IS_FATAL:-True}
 VIF_PLUGGING_TIMEOUT=${VIF_PLUGGING_TIMEOUT:-300}
 
+# The directory which contains files for Q_PLUGIN_EXTRA_CONF_FILES.
+# /etc/neutron is assumed by many of devstack plugins.  Do not change.
+_Q_PLUGIN_EXTRA_CONF_PATH=/etc/neutron
+
 # List of config file names in addition to the main plugin config file
-# See _configure_neutron_common() for details about setting it up
+# To add additional plugin config files, use ``neutron_server_config_add``
+# utility function.  For example:
+#
+#    ``neutron_server_config_add file1``
+#
+# These config files are relative to ``/etc/neutron``.  The above
+# example would specify ``--config-file /etc/neutron/file1`` for
+# neutron server.
 declare -a Q_PLUGIN_EXTRA_CONF_FILES
 
+# same as Q_PLUGIN_EXTRA_CONF_FILES, but with absolute path.
+declare -a _Q_PLUGIN_EXTRA_CONF_FILES_ABS
+
 
 Q_RR_CONF_FILE=$NEUTRON_CONF_DIR/rootwrap.conf
 if [[ "$Q_USE_ROOTWRAP" == "False" ]]; then
@@ -270,9 +284,23 @@
 # ---------
 
 function _determine_config_server {
+    if [[ "$Q_PLUGIN_EXTRA_CONF_PATH" != '' ]]; then
+        if [[ "$Q_PLUGIN_EXTRA_CONF_PATH" = "$_Q_PLUGIN_EXTRA_CONF_PATH" ]]; then
+            deprecated "Q_PLUGIN_EXTRA_CONF_PATH is deprecated"
+        else
+            die $LINENO "Q_PLUGIN_EXTRA_CONF_PATH is deprecated"
+        fi
+    fi
+    if [[ ${#Q_PLUGIN_EXTRA_CONF_FILES[@]} > 0 ]]; then
+        deprecated "Q_PLUGIN_EXTRA_CONF_FILES is deprecated.  Use neutron_server_config_add instead."
+    fi
+    for cfg_file in ${Q_PLUGIN_EXTRA_CONF_FILES[@]}; do
+        _Q_PLUGIN_EXTRA_CONF_FILES_ABS+=($_Q_PLUGIN_EXTRA_CONF_PATH/$cfg_file)
+    done
+
     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
+    for cfg_file in ${_Q_PLUGIN_EXTRA_CONF_FILES_ABS[@]}; do
         opts+=" --config-file $cfg_file"
     done
     echo "$opts"
@@ -423,7 +451,7 @@
 }
 
 # install_neutron_agent_packages() - Collect source and prepare
-function install_neutron_agent_packages {
+function install_neutron_agent_packages_mutnauq {
     # radvd doesn't come with the OS. Install it if the l3 service is enabled.
     if is_service_enabled q-l3; then
         install_package radvd
@@ -668,11 +696,6 @@
 
     # 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 additional plugin config files, set ``Q_PLUGIN_EXTRA_CONF_PATH`` and
-    # ``Q_PLUGIN_EXTRA_CONF_FILES``.  For example:
-    #
-    #    ``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
@@ -699,20 +722,6 @@
     # 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"
-    fi
-
-    # If additional config files exist, copy them over to neutron configuration
-    # directory
-    if [[ $Q_PLUGIN_EXTRA_CONF_PATH != '' ]]; then
-        local f
-        for (( f=0; $f < ${#Q_PLUGIN_EXTRA_CONF_FILES[@]}; f+=1 )); do
-            Q_PLUGIN_EXTRA_CONF_FILES[$f]=$Q_PLUGIN_EXTRA_CONF_PATH/${Q_PLUGIN_EXTRA_CONF_FILES[$f]}
-        done
-    fi
-
     if [ "$VIRT_DRIVER" = 'fake' ]; then
         # Disable arbitrary limits
         iniset $NEUTRON_CONF quotas quota_network -1
@@ -863,6 +872,11 @@
     fi
 }
 
+# mutnauq_server_config_add() - add server config file
+function mutnauq_server_config_add {
+    _Q_PLUGIN_EXTRA_CONF_FILES_ABS+=($1)
+}
+
 # _neutron_deploy_rootwrap_filters() - deploy rootwrap filters to $Q_CONF_ROOTWRAP_D (owned by root).
 function _neutron_deploy_rootwrap_filters {
     if [[ "$Q_USE_ROOTWRAP" == "False" ]]; then
diff --git a/lib/neutron_plugins/linuxbridge_agent b/lib/neutron_plugins/linuxbridge_agent
index d0de2f5..0c8ccb8 100644
--- a/lib/neutron_plugins/linuxbridge_agent
+++ b/lib/neutron_plugins/linuxbridge_agent
@@ -62,7 +62,9 @@
         LB_INTERFACE_MAPPINGS=$PHYSICAL_NETWORK:$LB_PHYSICAL_INTERFACE
     fi
     if [[ "$PUBLIC_BRIDGE" != "" ]] && [[ "$PUBLIC_PHYSICAL_NETWORK" != "" ]]; then
-        iniset /$Q_PLUGIN_CONF_FILE linux_bridge bridge_mappings "$PUBLIC_PHYSICAL_NETWORK:$PUBLIC_BRIDGE"
+        if is_service_enabled q-l3 || is_service_enabled neutron-l3; then
+            iniset /$Q_PLUGIN_CONF_FILE linux_bridge bridge_mappings "$PUBLIC_PHYSICAL_NETWORK:$PUBLIC_BRIDGE"
+        fi
     fi
     if [[ "$LB_INTERFACE_MAPPINGS" != "" ]]; then
         iniset /$Q_PLUGIN_CONF_FILE linux_bridge physical_interface_mappings $LB_INTERFACE_MAPPINGS
diff --git a/lib/neutron_plugins/ml2 b/lib/neutron_plugins/ml2
index e429714..c5a4c02 100644
--- a/lib/neutron_plugins/ml2
+++ b/lib/neutron_plugins/ml2
@@ -63,7 +63,7 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/ml2
     Q_PLUGIN_CONF_FILENAME=ml2_conf.ini
-    Q_PLUGIN_CLASS="neutron.plugins.ml2.plugin.Ml2Plugin"
+    Q_PLUGIN_CLASS="ml2"
     # The ML2 plugin delegates L3 routing/NAT functionality to
     # the L3 service plugin which must therefore be specified.
     _neutron_service_plugin_class_add $ML2_L3_PLUGIN
@@ -105,7 +105,7 @@
             if [[ -n "$PHYSICAL_NETWORK" ]]; then
                 Q_ML2_PLUGIN_FLAT_TYPE_OPTIONS+="${PHYSICAL_NETWORK},"
             fi
-            if [[ -n "$PUBLIC_PHYSICAL_NETWORK" ]]; then
+            if [[ -n "$PUBLIC_PHYSICAL_NETWORK" ]] && [[ "${PHYSICAL_NETWORK}" != "$PUBLIC_PHYSICAL_NETWORK" ]]; then
                 Q_ML2_PLUGIN_FLAT_TYPE_OPTIONS+="${PUBLIC_PHYSICAL_NETWORK},"
             fi
         fi
diff --git a/lib/neutron_plugins/openvswitch_agent b/lib/neutron_plugins/openvswitch_agent
index f009966..76a1a4f 100644
--- a/lib/neutron_plugins/openvswitch_agent
+++ b/lib/neutron_plugins/openvswitch_agent
@@ -97,8 +97,8 @@
 
         # Set OVS native interface for ovs-agent in compute node
         XEN_DOM0_IP=$(echo "$XENAPI_CONNECTION_URL" | cut -d "/" -f 3)
-        iniset /$Q_PLUGIN_CONF_FILE ovs ovsdb_connection tcp:$XEN_DOM0_IP:6640
-        iniset /$Q_PLUGIN_CONF_FILE ovs of_listen_address $HOST_IP
+        iniset /$Q_PLUGIN_CONF_FILE.domU ovs ovsdb_connection tcp:$XEN_DOM0_IP:6640
+        iniset /$Q_PLUGIN_CONF_FILE.domU ovs of_listen_address $HOST_IP
 
         # Set up domU's L2 agent:
 
diff --git a/lib/neutron_plugins/ovs_base b/lib/neutron_plugins/ovs_base
index 1004325..62a4d00 100644
--- a/lib/neutron_plugins/ovs_base
+++ b/lib/neutron_plugins/ovs_base
@@ -69,7 +69,11 @@
         restart_service openvswitch
         sudo systemctl enable openvswitch
     elif is_suse; then
-        restart_service openvswitch-switch
+        if [[ $DISTRO == "sle12" ]] && [[ $os_RELEASE -lt 12.2 ]]; then
+            restart_service openvswitch-switch
+        else
+            restart_service openvswitch
+        fi
     fi
 }
 
diff --git a/lib/neutron_plugins/services/l3 b/lib/neutron_plugins/services/l3
index 569a366..cd0c1ed 100644
--- a/lib/neutron_plugins/services/l3
+++ b/lib/neutron_plugins/services/l3
@@ -192,8 +192,8 @@
         fi
 
         if [[ "$IP_VERSION" =~ .*6 ]]; then
-            die_if_not_set $LINENO IPV6_PROVIDER_FIXED_RANGE "IPV6_PROVIDER_FIXED_RANGE has not been set, but Q_USE_PROVIDERNET_FOR_PUBLIC is true and IP_VERSION includes 6"
-            die_if_not_set $LINENO IPV6_PROVIDER_NETWORK_GATEWAY "IPV6_PROVIDER_NETWORK_GATEWAY has not been set, but Q_USE_PROVIDERNET_FOR_PUBLIC is true and IP_VERSION includes 6"
+            die_if_not_set $LINENO IPV6_PROVIDER_FIXED_RANGE "IPV6_PROVIDER_FIXED_RANGE has not been set, but Q_USE_PROVIDER_NETWORKING is true and IP_VERSION includes 6"
+            die_if_not_set $LINENO IPV6_PROVIDER_NETWORK_GATEWAY "IPV6_PROVIDER_NETWORK_GATEWAY has not been set, but Q_USE_PROVIDER_NETWORKING is true and IP_VERSION includes 6"
             if [ -z $SUBNETPOOL_V6_ID ]; then
                 fixed_range_v6=$IPV6_PROVIDER_FIXED_RANGE
             fi
@@ -337,7 +337,7 @@
     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
+    openstack --os-cloud devstack-admin --os-region "$REGION_NAME" router set --external-gateway $EXT_NET_ID $ROUTER_ID
 
     # This logic is specific to using the l3-agent for layer 3
     if is_service_enabled q-l3 || is_service_enabled neutron-l3;  then
@@ -385,7 +385,7 @@
     # 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
+        openstack --os-cloud devstack-admin --os-region "$REGION_NAME" set --external-gateway $EXT_NET_ID $ROUTER_ID
     fi
 
     # This logic is specific to using the l3-agent for layer 3
diff --git a/lib/nova b/lib/nova
index ca9a6c7..63c4e37 100644
--- a/lib/nova
+++ b/lib/nova
@@ -85,9 +85,6 @@
 # NOTE: Set ``FORCE_CONFIG_DRIVE="False"`` to turn OFF config drive
 FORCE_CONFIG_DRIVE=${FORCE_CONFIG_DRIVE:-"False"}
 
-# Option to initialize CellsV2 environment
-NOVA_CONFIGURE_CELLSV2=$(trueorfalse False NOVA_CONFIGURE_CELLSV2)
-
 # Nova supports pluggable schedulers.  The default ``FilterScheduler``
 # should work in most cases.
 SCHEDULER=${SCHEDULER:-filter_scheduler}
@@ -666,6 +663,7 @@
     if [ -n "$FLAT_INTERFACE" ]; then
         iniset $NOVA_CONF DEFAULT flat_interface "$FLAT_INTERFACE"
     fi
+    iniset $NOVA_CONF DEFAULT use_neutron False
 }
 
 # create_nova_keys_dir() - Part of the init_nova() process
@@ -679,11 +677,12 @@
     # All nova components talk to a central database.
     # Only do this step once on the API node for an entire cluster.
     if is_service_enabled $DATABASE_BACKENDS && is_service_enabled n-api; then
+        recreate_database $NOVA_API_DB
+        $NOVA_BIN_DIR/nova-manage --config-file $NOVA_CONF api_db sync
+
         # (Re)create nova databases
         recreate_database nova
-        if [ "$NOVA_CONFIGURE_CELLSV2" != "False" ]; then
-            recreate_database nova_api_cell0
-        fi
+        recreate_database nova_api_cell0
 
         # Migrate nova database. If "nova-manage cell_v2 simple_cell_setup" has
         # been run this migrates the "nova" and "nova_api_cell0" database.
@@ -694,9 +693,6 @@
             recreate_database $NOVA_CELLS_DB
         fi
 
-        recreate_database $NOVA_API_DB
-        $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 --config-file $NOVA_CONF db online_data_migrations
@@ -827,7 +823,7 @@
         run_process n-cpu "$NOVA_BIN_DIR/nova-compute --config-file $compute_cell_conf" $LIBVIRT_GROUP
     elif [[ "$VIRT_DRIVER" = 'lxd' ]]; then
         run_process n-cpu "$NOVA_BIN_DIR/nova-compute --config-file $compute_cell_conf" $LXD_GROUP
-    elif [[ "$VIRT_DRIVER" = 'docker' ]]; then
+    elif [[ "$VIRT_DRIVER" = 'docker' || "$VIRT_DRIVER" = 'zun' ]]; then
         run_process n-cpu "$NOVA_BIN_DIR/nova-compute --config-file $compute_cell_conf" $DOCKER_GROUP
     elif [[ "$VIRT_DRIVER" = 'fake' ]]; then
         local i
diff --git a/lib/nova_plugins/hypervisor-libvirt b/lib/nova_plugins/hypervisor-libvirt
index 167ab6f..f3c8add 100644
--- a/lib/nova_plugins/hypervisor-libvirt
+++ b/lib/nova_plugins/hypervisor-libvirt
@@ -105,6 +105,16 @@
     if [[ "$ENABLE_FILE_INJECTION" == "True" ]] ; then
         if is_ubuntu; then
             install_package python-guestfs
+            # NOTE(andreaf) Ubuntu kernel can only be read by root, which breaks libguestfs:
+            # https://bugs.launchpad.net/ubuntu/+source/linux/+bug/759725)
+            INSTALLED_KERNELS="$(ls /boot/vmlinuz-*)"
+            for kernel in $INSTALLED_KERNELS; do
+                STAT_OVERRIDE="root root 644 ${kernel}"
+                # unstack won't remove the statoverride, so make this idempotent
+                if [[ ! $(dpkg-statoverride --list | grep "$STAT_OVERRIDE") ]]; then
+                    sudo dpkg-statoverride --add --update $STAT_OVERRIDE
+                fi
+            done
         elif is_fedora || is_suse; then
             install_package python-libguestfs
         fi
diff --git a/lib/nova_plugins/hypervisor-xenserver b/lib/nova_plugins/hypervisor-xenserver
index b053856..0046a36 100644
--- a/lib/nova_plugins/hypervisor-xenserver
+++ b/lib/nova_plugins/hypervisor-xenserver
@@ -48,6 +48,21 @@
     if [ -z "$XENAPI_CONNECTION_URL" ]; then
         die $LINENO "XENAPI_CONNECTION_URL is not specified"
     fi
+
+    # Check os-xenapi plugin is enabled
+    local plugins="${DEVSTACK_PLUGINS}"
+    local plugin
+    local found=0
+    for plugin in ${plugins//,/ }; do
+        if [[ "$plugin" = "os-xenapi" ]]; then
+            found=1
+            break
+        fi
+    done
+    if [[ $found -ne 1 ]]; then
+        die $LINENO "os-xenapi plugin is not specified. Please enable this plugin in local.conf"
+    fi
+
     read_password XENAPI_PASSWORD "ENTER A PASSWORD TO USE FOR XEN."
     iniset $NOVA_CONF DEFAULT compute_driver "xenapi.XenAPIDriver"
     iniset $NOVA_CONF xenserver connection_url "$XENAPI_CONNECTION_URL"
@@ -64,14 +79,6 @@
     local ssh_dom0
     ssh_dom0="sudo -u $DOMZERO_USER ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@$dom0_ip"
 
-    # Find where the plugins should go in dom0
-    xen_functions=`cat $TOP_DIR/tools/xen/functions`
-    PLUGIN_DIR=`$ssh_dom0 "$xen_functions; set -eux; xapi_plugin_location"`
-
-    # install nova plugins to dom0
-    tar -czf - -C $NOVA_DIR/plugins/xenserver/xenapi/etc/xapi.d/plugins/ ./ |
-        $ssh_dom0 "tar -xzf - -C $PLUGIN_DIR && chmod a+x $PLUGIN_DIR/*"
-
     # install console logrotate script
     tar -czf - -C $NOVA_DIR/tools/xenserver/ rotate_xen_guest_logs.sh |
         $ssh_dom0 'tar -xzf - -C /root/ && chmod +x /root/rotate_xen_guest_logs.sh && mkdir -p /var/log/xen/guest'
@@ -107,7 +114,9 @@
 
 # install_nova_hypervisor() - Install external components
 function install_nova_hypervisor {
-    pip_install_gr xenapi
+    # xenapi functionality is now included in os-xenapi library which houses the plugin
+    # so this function intentionally left blank
+    :
 }
 
 # start_nova_hypervisor - Start any required external services
diff --git a/lib/placement b/lib/placement
index 165c670..871e282 100644
--- a/lib/placement
+++ b/lib/placement
@@ -47,7 +47,6 @@
 # Public facing bits
 PLACEMENT_SERVICE_PROTOCOL=${PLACEMENT_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
 PLACEMENT_SERVICE_HOST=${PLACEMENT_SERVICE_HOST:-$SERVICE_HOST}
-PLACEMENT_SERVICE_PORT=${PLACEMENT_SERVICE_PORT:-8778}
 
 # Functions
 # ---------
@@ -55,7 +54,7 @@
 # Test if any placement services are enabled
 # is_placement_enabled
 function is_placement_enabled {
-    [[ ,${ENABLED_SERVICES} =~ ,"placement-" ]] && return 0
+    [[ ,${ENABLED_SERVICES} =~ ,"placement-api" ]] && return 0
     return 1
 }
 
@@ -68,7 +67,6 @@
 # _config_placement_apache_wsgi() - Set WSGI config files
 function _config_placement_apache_wsgi {
     local placement_api_apache_conf
-    local placement_api_port=$PLACEMENT_SERVICE_PORT
     local venv_path=""
     local nova_bin_dir=""
     nova_bin_dir=$(get_python_exec_prefix)
@@ -89,7 +87,6 @@
 
     sudo cp $FILES/apache-placement-api.template $placement_api_apache_conf
     sudo sed -e "
-        s|%PUBLICPORT%|$placement_api_port|g;
         s|%APACHE_NAME%|$APACHE_NAME|g;
         s|%PUBLICWSGI%|$nova_bin_dir/nova-placement-api|g;
         s|%SSLENGINE%|$placement_ssl|g;
@@ -101,19 +98,14 @@
     " -i $placement_api_apache_conf
 }
 
-# configure_placement() - Set config files, create data dirs, etc
-function configure_placement {
-    if [ "$PLACEMENT_DB_ENABLED" != False ]; then
-        iniset $PLACEMENT_CONF placement_database connection `database_connection_url placement`
-    fi
-
+function configure_placement_nova_compute {
     iniset $NOVA_CONF placement auth_type "password"
     iniset $NOVA_CONF placement auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v3"
     iniset $NOVA_CONF placement username placement
     iniset $NOVA_CONF placement password "$SERVICE_PASSWORD"
-    iniset $NOVA_CONF placement user_domain_name "Default"
+    iniset $NOVA_CONF placement user_domain_name "$SERVICE_DOMAIN_NAME"
     iniset $NOVA_CONF placement project_name "$SERVICE_TENANT_NAME"
-    iniset $NOVA_CONF placement project_domain_name "Default"
+    iniset $NOVA_CONF placement project_domain_name "$SERVICE_DOMAIN_NAME"
     iniset $NOVA_CONF placement os_region_name "$REGION_NAME"
     # TODO(cdent): auth_strategy, which is common to see in these
     # blocks is not currently used here. For the time being the
@@ -121,7 +113,13 @@
     # established by the nova api. This avoids, for the time, being,
     # creating redundant configuration items that are just used for
     # testing.
+}
 
+# configure_placement() - Set config files, create data dirs, etc
+function configure_placement {
+    if [ "$PLACEMENT_DB_ENABLED" != False ]; then
+        iniset $PLACEMENT_CONF placement_database connection `database_connection_url placement`
+    fi
     _config_placement_apache_wsgi
 }
 
@@ -160,10 +158,6 @@
 
 # start_placement_api() - Start the API processes ahead of other things
 function start_placement_api {
-    # Get right service port for testing
-    local service_port=$PLACEMENT_SERVICE_PORT
-    local placement_api_port=$PLACEMENT_SERVICE_PORT
-
     enable_apache_site placement-api
     restart_apache_server
     tail_log placement-api /var/log/$APACHE_NAME/placement-api.log
diff --git a/lib/rpc_backend b/lib/rpc_backend
index 97b1aa4..a21f781 100644
--- a/lib/rpc_backend
+++ b/lib/rpc_backend
@@ -25,6 +25,9 @@
 set +o xtrace
 
 RABBIT_USERID=${RABBIT_USERID:-stackrabbit}
+if is_service_enabled rabbit; then
+    RABBIT_HOST=${RABBIT_HOST:-$SERVICE_HOST}
+fi
 
 # Functions
 # ---------
diff --git a/lib/swift b/lib/swift
index b175f2e..03fd454 100644
--- a/lib/swift
+++ b/lib/swift
@@ -454,7 +454,6 @@
     # out. Make sure we uncomment Tempauth after we uncomment Keystoneauth
     # otherwise, this code also sets the reseller_prefix for Keystoneauth.
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} filter:tempauth account_autocreate
-    iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} filter:tempauth reseller_prefix
     iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:tempauth reseller_prefix "TEMPAUTH"
 
     if is_service_enabled swift3; then
@@ -809,10 +808,10 @@
         local proxy_port=${SWIFT_DEFAULT_BIND_PORT}
         start_tls_proxy swift '*' $proxy_port $SERVICE_HOST $SWIFT_DEFAULT_BIND_PORT_INT
     fi
-    run_process s-proxy "$SWIFT_DIR/bin/swift-proxy-server ${SWIFT_CONF_DIR}/proxy-server.conf -v"
+    run_process s-proxy "swift-proxy-server ${SWIFT_CONF_DIR}/proxy-server.conf -v"
     if [[ ${SWIFT_REPLICAS} == 1 ]]; then
         for type in object container account; do
-            run_process s-${type} "$SWIFT_DIR/bin/swift-${type}-server ${SWIFT_CONF_DIR}/${type}-server/1.conf -v"
+            run_process s-${type} "swift-${type}-server ${SWIFT_CONF_DIR}/${type}-server/1.conf -v"
         done
     fi
 
diff --git a/lib/tempest b/lib/tempest
index a1b84b6..5a07229 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -263,6 +263,9 @@
     # Identity
     iniset $TEMPEST_CONFIG identity uri "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:5000/v2.0/"
     iniset $TEMPEST_CONFIG identity uri_v3 "$KEYSTONE_SERVICE_URI_V3"
+    iniset $TEMPEST_CONFIG identity user_lockout_failure_attempts $KEYSTONE_LOCKOUT_FAILURE_ATTEMPTS
+    iniset $TEMPEST_CONFIG identity user_lockout_duration $KEYSTONE_LOCKOUT_DURATION
+    iniset $TEMPEST_CONFIG identity user_unique_last_password_count $KEYSTONE_UNIQUE_LAST_PASSWORD_COUNT
     # Use domain scoped tokens for admin v3 tests, v3 dynamic credentials of v3 account generation
     iniset $TEMPEST_CONFIG identity admin_domain_scope True
     if [[ "$TEMPEST_HAS_ADMIN" == "True" ]]; then
@@ -287,8 +290,9 @@
     fi
 
     # Identity Features
-    # TODO(rodrigods): Remove the reseller flag when Kilo and Liberty are end of life.
-    iniset $TEMPEST_CONFIG identity-feature-enabled reseller True
+    if [[ "$KEYSTONE_SECURITY_COMPLIANCE_ENABLED" = True ]]; then
+        iniset $TEMPEST_CONFIG identity-feature-enabled security_compliance True
+    fi
 
     # Image
     # We want to be able to override this variable in the gate to avoid
@@ -349,8 +353,6 @@
         iniset $TEMPEST_CONFIG compute max_microversion $tempest_compute_max_microversion
     fi
 
-    # TODO(mriedem): Remove allow_port_security_disabled after liberty-eol.
-    iniset $TEMPEST_CONFIG compute-feature-enabled allow_port_security_disabled True
     iniset $TEMPEST_CONFIG compute-feature-enabled personality ${ENABLE_FILE_INJECTION:-False}
     iniset $TEMPEST_CONFIG compute-feature-enabled resize True
     iniset $TEMPEST_CONFIG compute-feature-enabled live_migration ${LIVE_MIGRATION_AVAILABLE:-False}
@@ -432,8 +434,7 @@
     iniset $TEMPEST_CONFIG validation network_for_ssh $TEMPEST_SSH_NETWORK_NAME
 
     # Volume
-    # TODO(obutenko): Remove snapshot_backup when liberty-eol happens.
-    iniset $TEMPEST_CONFIG volume-feature-enabled snapshot_backup True
+    iniset $TEMPEST_CONFIG volume-feature-enabled manage_snapshot $(trueorfalse True TEMPEST_VOLUME_MANAGE_SNAPSHOT)
     # 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
     # TODO(ameade): Remove the api_v3 flag when Mitaka and Liberty are end of life.
@@ -488,12 +489,6 @@
         iniset $TEMPEST_CONFIG volume storage_protocol "$TEMPEST_STORAGE_PROTOCOL"
     fi
 
-    # Dashboard
-    iniset $TEMPEST_CONFIG dashboard dashboard_url "http://$SERVICE_HOST/"
-
-    # CLI
-    iniset $TEMPEST_CONFIG cli cli_dir $NOVA_BIN_DIR
-
     # Baremetal
     if [ "$VIRT_DRIVER" = "ironic" ] ; then
         iniset $TEMPEST_CONFIG baremetal driver_enabled True
diff --git a/pkg/elasticsearch.sh b/pkg/elasticsearch.sh
index 856eaff..fefd454 100755
--- a/pkg/elasticsearch.sh
+++ b/pkg/elasticsearch.sh
@@ -83,7 +83,7 @@
         return
     fi
     if is_ubuntu; then
-        is_package_installed openjdk-7-jre-headless || install_package openjdk-7-jre-headless
+        is_package_installed default-jre-headless || install_package default-jre-headless
 
         sudo dpkg -i ${FILES}/elasticsearch-${ELASTICSEARCH_VERSION}.deb
         sudo update-rc.d elasticsearch defaults 95 10
diff --git a/stack.sh b/stack.sh
index 74edb10..7d440a7 100755
--- a/stack.sh
+++ b/stack.sh
@@ -572,9 +572,7 @@
 source $TOP_DIR/lib/placement
 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
 source $TOP_DIR/lib/dlm
@@ -665,7 +663,6 @@
 # In multi node DevStack, second node needs ``RABBIT_USERID``, but rabbit
 # isn't enabled.
 if is_service_enabled rabbit; then
-    RABBIT_HOST=${RABBIT_HOST:-$SERVICE_HOST}
     read_password RABBIT_PASSWORD "ENTER A PASSWORD TO USE FOR RABBIT."
 fi
 
@@ -800,9 +797,6 @@
 if is_service_enabled neutron nova horizon; then
     install_neutronclient
 fi
-if is_service_enabled heat horizon; then
-    install_heatclient
-fi
 
 # Install shared libraries
 if is_service_enabled cinder nova; then
@@ -873,6 +867,16 @@
     configure_placement
 fi
 
+# create a placement-client fake service to know we need to configure
+# placement connectivity. We configure the placement service for nova
+# if placement-api or placement-client is active, and n-cpu on the
+# same box.
+if is_service_enabled placement placement-client; then
+    if is_service_enabled n-cpu; then
+        configure_placement_nova_compute
+    fi
+fi
+
 if is_service_enabled horizon; then
     # django openstack_auth
     install_django_openstack_auth
@@ -880,13 +884,6 @@
     stack_install_service horizon
 fi
 
-if is_service_enabled heat; then
-    stack_install_service heat
-    install_heat_other
-    cleanup_heat
-    configure_heat
-fi
-
 if is_service_enabled tls-proxy || [ "$USE_SSL" == "True" ]; then
     fix_system_ca_bundle_path
 fi
@@ -1073,10 +1070,6 @@
         create_swift_accounts
     fi
 
-    if is_service_enabled heat; then
-        create_heat_accounts
-    fi
-
 fi
 
 # Write a clouds.yaml file
@@ -1289,18 +1282,6 @@
     create_volume_types
 fi
 
-# Configure and launch Heat engine, api and metadata
-if is_service_enabled heat; then
-    # Initialize heat
-    echo_summary "Configuring Heat"
-    init_heat
-    echo_summary "Starting Heat"
-    start_heat
-    if [ "$HEAT_BUILD_PIP_MIRROR" = "True" ]; then
-        echo_summary "Building Heat pip mirror"
-        build_heat_pip_mirror
-    fi
-fi
 
 if is_service_enabled horizon; then
     echo_summary "Starting Horizon"
@@ -1385,8 +1366,16 @@
 # ----------------------
 
 # Do this late because it requires compute hosts to have started
-if is_service_enabled n-api && [ "$NOVA_CONFIGURE_CELLSV2" == "True" ]; then
-    create_cell
+if is_service_enabled n-api; then
+    if is_service_enabled n-cpu; then
+        create_cell
+    else
+        # Some CI systems like Hyper-V build the control plane on
+        # Linux, and join in non Linux Computes after setup. This
+        # allows them to delay the processing until after their whole
+        # environment is up.
+        echo_summary "SKIPPING Cell setup because n-cpu is not enabled. You will have to do this manually before you have a working environment."
+    fi
 fi
 
 # Bash completion
@@ -1411,6 +1400,9 @@
 # Phase: test-config
 run_phase stack test-config
 
+# Apply late configuration from ``local.conf`` if it exists for layer 2 services
+# Phase: test-config
+merge_config_group $TOP_DIR/local.conf test-config
 
 # Fin
 # ===
diff --git a/stackrc b/stackrc
index 9799d1d..19f5b53 100644
--- a/stackrc
+++ b/stackrc
@@ -54,6 +54,8 @@
     ENABLED_SERVICES=key
     # Nova - services to support libvirt based openstack clouds
     ENABLED_SERVICES+=,n-api,n-cpu,n-cond,n-sch,n-novnc,n-cauth
+    # Placement service needed for Nova
+    ENABLED_SERVICES+=,placement-api,placement-client
     # Glance services needed for Nova
     ENABLED_SERVICES+=,g-api,g-reg
     # Cinder
@@ -101,12 +103,12 @@
 fi
 
 # Control whether Python 3 should be used.
-export USE_PYTHON3=${USE_PYTHON3:-False}
+export USE_PYTHON3=$(trueorfalse False USE_PYTHON3)
 
 # When Python 3 is supported by an application, adding the specific
 # version of Python 3 to this variable will install the app using that
 # version of the interpreter instead of 2.7.
-export PYTHON3_VERSION=${PYTHON3_VERSION:-3.4}
+export PYTHON3_VERSION=${PYTHON3_VERSION:-3.5}
 
 # Just to be more explicit on the Python 2 version to use.
 export PYTHON2_VERSION=${PYTHON2_VERSION:-2.7}
@@ -229,10 +231,6 @@
 GLANCE_REPO=${GLANCE_REPO:-${GIT_BASE}/openstack/glance.git}
 GLANCE_BRANCH=${GLANCE_BRANCH:-master}
 
-# heat service
-HEAT_REPO=${HEAT_REPO:-${GIT_BASE}/openstack/heat.git}
-HEAT_BRANCH=${HEAT_BRANCH:-master}
-
 # django powered web control panel for openstack
 HORIZON_REPO=${HORIZON_REPO:-${GIT_BASE}/openstack/horizon.git}
 HORIZON_BRANCH=${HORIZON_BRANCH:-master}
@@ -291,10 +289,6 @@
 GITREPO["python-glanceclient"]=${GLANCECLIENT_REPO:-${GIT_BASE}/openstack/python-glanceclient.git}
 GITBRANCH["python-glanceclient"]=${GLANCECLIENT_BRANCH:-master}
 
-# python heat client library
-GITREPO["python-heatclient"]=${HEATCLIENT_REPO:-${GIT_BASE}/openstack/python-heatclient.git}
-GITBRANCH["python-heatclient"]=${HEATCLIENT_BRANCH:-master}
-
 # ironic client
 GITREPO["python-ironicclient"]=${IRONICCLIENT_REPO:-${GIT_BASE}/openstack/python-ironicclient.git}
 GITBRANCH["python-ironicclient"]=${IRONICCLIENT_BRANCH:-master}
@@ -579,7 +573,7 @@
     lxd)
         LXD_GROUP=${LXD_GROUP:-"lxd"}
         ;;
-    docker)
+    docker|zun)
         DOCKER_GROUP=${DOCKER_GROUP:-"docker"}
         ;;
     fake)
@@ -827,6 +821,10 @@
 # Use native SSL for servers in ``SSL_ENABLED_SERVICES``
 USE_SSL=$(trueorfalse False USE_SSL)
 
+# We may not need to recreate database in case 2 Keystone services
+# sharing the same database. It would be useful for multinode Grenade tests.
+RECREATE_KEYSTONE_DB=$(trueorfalse True RECREATE_KEYSTONE_DB)
+
 # ebtables is inherently racey. If you run it by two or more processes
 # simultaneously it will collide, badly, in the kernel and produce
 # failures or corruption of ebtables. The only way around it is for
diff --git a/tests/test_libs_from_pypi.sh b/tests/test_libs_from_pypi.sh
index fb55023..415fec5 100755
--- a/tests/test_libs_from_pypi.sh
+++ b/tests/test_libs_from_pypi.sh
@@ -32,7 +32,7 @@
 ALL_LIBS="python-novaclient oslo.config pbr oslo.context"
 ALL_LIBS+=" python-keystoneclient taskflow oslo.middleware pycadf"
 ALL_LIBS+=" python-glanceclient python-ironicclient"
-ALL_LIBS+=" oslo.messaging oslo.log cliff python-heatclient stevedore"
+ALL_LIBS+=" oslo.messaging oslo.log cliff stevedore"
 ALL_LIBS+=" python-cinderclient glance_store oslo.concurrency oslo.db"
 ALL_LIBS+=" oslo.versionedobjects oslo.vmware keystonemiddleware"
 ALL_LIBS+=" oslo.serialization django_openstack_auth"
diff --git a/tests/test_meta_config.sh b/tests/test_meta_config.sh
index 92f9c01..087aaf4 100755
--- a/tests/test_meta_config.sh
+++ b/tests/test_meta_config.sh
@@ -29,6 +29,10 @@
     exit -1
 }
 
+function warn {
+    return 0
+}
+
 TEST_1C_ADD="[eee]
 type=new
 multi = foo2"
@@ -92,7 +96,7 @@
 [[test3|test-space.conf]]
 [DEFAULT]
 attribute=value
- 
+
 # the above line has a single space
 
 [[test4|\$TEST4_DIR/\$TEST4_FILE]]
@@ -378,11 +382,10 @@
 
 echo -n "merge_config_group test9 undefined conf file: "
 set +e
-# function is expected to fail and exit, running it
-# in a subprocess to let this script proceed
+# function is expected to trigger warn and continue
 (merge_config_group test.conf test9)
 VAL=$?
-EXPECT_VAL=255
+EXPECT_VAL=0
 check_result "$VAL" "$EXPECT_VAL"
 set -e
 
diff --git a/tools/install_prereqs.sh b/tools/install_prereqs.sh
index 8895e1e..da59093 100755
--- a/tools/install_prereqs.sh
+++ b/tools/install_prereqs.sh
@@ -83,6 +83,9 @@
 
 if python3_enabled; then
     install_python3
+    export PYTHON=$(which python${PYTHON3_VERSION} 2>/dev/null || which python3 2>/dev/null)
+else
+    export PYTHON=$(which python 2>/dev/null)
 fi
 
 # Mark end of run
diff --git a/tools/xen/xenrc b/tools/xen/xenrc
index bb27454..2161247 100644
--- a/tools/xen/xenrc
+++ b/tools/xen/xenrc
@@ -101,6 +101,7 @@
 
 ## Note that the lines below are coming from stackrc to support
 ## new-style config files
+source $RC_DIR/functions-common
 
 # allow local overrides of env variables, including repo config
 if [[ -f $RC_DIR/localrc ]]; then
diff --git a/unstack.sh b/unstack.sh
index c05d1f0..b0ebaf7 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -66,9 +66,7 @@
 source $TOP_DIR/lib/placement
 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
 source $TOP_DIR/lib/dlm
@@ -99,10 +97,6 @@
 
 # Call service stop
 
-if is_service_enabled heat; then
-    stop_heat
-fi
-
 if is_service_enabled nova; then
     stop_nova
 fi