Merge "Warn instead of die on undefined config names"
diff --git a/doc/source/plugin-registry.rst b/doc/source/plugin-registry.rst
index 9a75090..cb9c437 100644
--- a/doc/source/plugin-registry.rst
+++ b/doc/source/plugin-registry.rst
@@ -79,6 +79,7 @@
 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>`__
 monasca-analytics                      `git://git.openstack.org/openstack/monasca-analytics <https://git.openstack.org/cgit/openstack/monasca-analytics>`__
@@ -94,6 +95,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>`__
@@ -120,6 +123,7 @@
 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>`__
@@ -127,6 +131,7 @@
 octavia                                `git://git.openstack.org/openstack/octavia <https://git.openstack.org/cgit/openstack/octavia>`__
 osprofiler                             `git://git.openstack.org/openstack/osprofiler <https://git.openstack.org/cgit/openstack/osprofiler>`__
 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-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/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-common b/functions-common
index cc1d42b..8d03b88 100644
--- a/functions-common
+++ b/functions-common
@@ -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/python b/inc/python
index e4cfab8..5a9a9ed 100644
--- a/inc/python
+++ b/inc/python
@@ -76,6 +76,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 +144,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/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/horizon b/lib/horizon
index 830da09..4cabbe4 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -81,7 +81,11 @@
     # 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)
+    if python3_enabled; then
+        (cd $HORIZON_DIR; python${PYTHON3_VERSION} manage.py compilemessages)
+    else
+        (cd $HORIZON_DIR; python manage.py compilemessages)
+    fi
 
     # ``local_settings.py`` is used to override horizon default settings.
     local local_settings=$HORIZON_DIR/openstack_dashboard/local/local_settings.py
@@ -162,7 +166,11 @@
         git_clone_by_name "django_openstack_auth"
         # Compile message catalogs before installation
         _prepare_message_catalog_compilation
-        (cd $dir; python setup.py compile_catalog)
+        if python3_enabled; then
+            (cd $dir; python${PYTHON3_VERSION} setup.py compile_catalog)
+        else
+            (cd $dir; python setup.py compile_catalog)
+        fi
         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 fd1d1d4..825fe44 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -445,14 +445,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.
@@ -488,8 +490,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/neutron b/lib/neutron
index d30e185..852787d 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -90,6 +90,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 {
@@ -568,6 +572,15 @@
     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 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..37d2783 100644
--- a/lib/neutron-legacy
+++ b/lib/neutron-legacy
@@ -423,7 +423,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
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/placement b/lib/placement
index 165c670..93b72eb 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,12 +98,7 @@
     " -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
@@ -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/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 f4bac30..0aaa604 100755
--- a/stack.sh
+++ b/stack.sh
@@ -573,7 +573,6 @@
 source $TOP_DIR/lib/cinder
 source $TOP_DIR/lib/swift
 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
@@ -869,6 +868,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
diff --git a/stackrc b/stackrc
index e7771cf..7ce6c51 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}
@@ -819,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/unstack.sh b/unstack.sh
index 6cd039f..b0ebaf7 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -67,7 +67,6 @@
 source $TOP_DIR/lib/cinder
 source $TOP_DIR/lib/swift
 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