Merge "Updated from generate-devstack-plugins-list"
diff --git a/.zuul.yaml b/.zuul.yaml
index 7ac30d8..21d1a97 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -19,6 +19,16 @@
           - controller
 
 - nodeset:
+    name: openstack-single-node-xenial
+    nodes:
+      - name: controller
+        label: ubuntu-xenial
+    groups:
+      - name: tempest
+        nodes:
+          - controller
+
+- nodeset:
     name: devstack-single-node-centos-7
     nodes:
       - name: controller
@@ -241,8 +251,8 @@
       This base job can be used for single node and multinode devstack jobs.
 
       With a single node nodeset, this job sets up an "all-in-one" (aio)
-      devstack with the six OpenStack services included in the devstack tree:
-      keystone, glance, cinder, neutron, nova and swift.
+      devstack with the seven OpenStack services included in the devstack tree:
+      keystone, glance, cinder, neutron, nova, placement, and swift.
 
       With a two node nodeset, this job sets up an aio + compute node.
       The controller can be customised using host-vars.controller, the
@@ -265,6 +275,7 @@
       - git.openstack.org/openstack/keystone
       - git.openstack.org/openstack/neutron
       - git.openstack.org/openstack/nova
+      - git.openstack.org/openstack/placement
       - git.openstack.org/openstack/swift
     timeout: 7200
     vars:
diff --git a/inc/python b/inc/python
index d8b8169..5fb7245 100644
--- a/inc/python
+++ b/inc/python
@@ -490,17 +490,6 @@
     _setup_package_with_constraints_edit $project_dir -e $extras
 }
 
-# determine if a project as specified by directory is in
-# projects.txt. This will not be an exact match because we throw away
-# the namespacing when we clone, but it should be good enough in all
-# practical ways.
-function is_in_projects_txt {
-    local project_dir=$1
-    local project_name
-    project_name=$(basename $project_dir)
-    grep -q "/$project_name\$" $REQUIREMENTS_DIR/projects.txt
-}
-
 # ``pip install -e`` the package, which processes the dependencies
 # using pip before running `setup.py develop`
 #
diff --git a/lib/placement b/lib/placement
index a1602ba..da69e39 100644
--- a/lib/placement
+++ b/lib/placement
@@ -3,9 +3,6 @@
 # lib/placement
 # Functions to control the configuration and operation of the **Placement** service
 #
-# Currently the placement service is embedded in nova. Eventually we
-# expect this to change so this file is started as a separate entity
-# despite making use of some *NOVA* variables and files.
 
 # Dependencies:
 #
@@ -29,23 +26,21 @@
 # Defaults
 # --------
 
-PLACEMENT_CONF_DIR=/etc/nova
-PLACEMENT_CONF=$PLACEMENT_CONF_DIR/nova.conf
-PLACEMENT_AUTH_STRATEGY=${PLACEMENT_AUTH_STRATEGY:-placement}
-# Nova virtual environment
+PLACEMENT_DIR=$DEST/placement
+PLACEMENT_CONF_DIR=/etc/placement
+PLACEMENT_CONF=$PLACEMENT_CONF_DIR/placement.conf
+PLACEMENT_AUTH_CACHE_DIR=${PLACEMENT_AUTH_CACHE_DIR:-/var/cache/placement}
+PLACEMENT_AUTH_STRATEGY=${PLACEMENT_AUTH_STRATEGY:-keystone}
+# Placement virtual environment
 if [[ ${USE_VENV} = True ]]; then
-    PROJECT_VENV["nova"]=${NOVA_DIR}.venv
-    PLACEMENT_BIN_DIR=${PROJECT_VENV["nova"]}/bin
+    PROJECT_VENV["placement"]=${PLACEMENT_DIR}.venv
+    PLACEMENT_BIN_DIR=${PROJECT_VENV["placement"]}/bin
 else
     PLACEMENT_BIN_DIR=$(get_python_exec_prefix)
 fi
-PLACEMENT_UWSGI=$PLACEMENT_BIN_DIR/nova-placement-api
+PLACEMENT_UWSGI=$PLACEMENT_BIN_DIR/placement-api
 PLACEMENT_UWSGI_CONF=$PLACEMENT_CONF_DIR/placement-uwsgi.ini
 
-# The placement service can optionally use a separate database
-# connection. Set PLACEMENT_DB_ENABLED to True to use it.
-PLACEMENT_DB_ENABLED=$(trueorfalse False PLACEMENT_DB_ENABLED)
-
 if is_service_enabled tls-proxy; then
     PLACEMENT_SERVICE_PROTOCOL="https"
 fi
@@ -67,30 +62,28 @@
 # cleanup_placement() - Remove residual data files, anything left over from previous
 # runs that a clean run would need to clean up
 function cleanup_placement {
-    sudo rm -f $(apache_site_config_for nova-placement-api)
     sudo rm -f $(apache_site_config_for placement-api)
     remove_uwsgi_config "$PLACEMENT_UWSGI_CONF" "$PLACEMENT_UWSGI"
+    sudo rm -f $PLACEMENT_AUTH_CACHE_DIR/*
 }
 
 # _config_placement_apache_wsgi() - Set WSGI config files
 function _config_placement_apache_wsgi {
     local placement_api_apache_conf
     local venv_path=""
-    local nova_bin_dir=""
-    nova_bin_dir=$(get_python_exec_prefix)
+    local placement_bin_dir=""
+    placement_bin_dir=$(get_python_exec_prefix)
     placement_api_apache_conf=$(apache_site_config_for placement-api)
 
-    # reuse nova's venv if there is one as placement code lives
-    # there
     if [[ ${USE_VENV} = True ]]; then
-        venv_path="python-path=${PROJECT_VENV["nova"]}/lib/$(python_version)/site-packages"
-        nova_bin_dir=${PROJECT_VENV["nova"]}/bin
+        venv_path="python-path=${PROJECT_VENV["placement"]}/lib/$(python_version)/site-packages"
+        placement_bin_dir=${PROJECT_VENV["placement"]}/bin
     fi
 
     sudo cp $FILES/apache-placement-api.template $placement_api_apache_conf
     sudo sed -e "
         s|%APACHE_NAME%|$APACHE_NAME|g;
-        s|%PUBLICWSGI%|$nova_bin_dir/nova-placement-api|g;
+        s|%PUBLICWSGI%|$placement_bin_dir/placement-api|g;
         s|%SSLENGINE%|$placement_ssl|g;
         s|%SSLCERTFILE%|$placement_certfile|g;
         s|%SSLKEYFILE%|$placement_keyfile|g;
@@ -110,19 +103,23 @@
     iniset $conf placement user_domain_name "$SERVICE_DOMAIN_NAME"
     iniset $conf placement project_name "$SERVICE_TENANT_NAME"
     iniset $conf placement project_domain_name "$SERVICE_DOMAIN_NAME"
-    # TODO(cdent): auth_strategy, which is common to see in these
-    # blocks is not currently used here. For the time being the
-    # placement api uses the auth_strategy configuration setting
-    # established by the nova api. This avoids, for the time, being,
-    # creating redundant configuration items that are just used for
-    # testing.
+    iniset $conf placement auth_strategy $PLACEMENT_AUTH_STRATEGY
+}
+
+# create_placement_conf() - Write config
+function create_placement_conf {
+    rm -f $PLACEMENT_CONF
+    iniset $PLACEMENT_CONF placement_database connection `database_connection_url placement`
+    iniset $PLACEMENT_CONF DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL"
+    iniset $PLACEMENT_CONF api auth_strategy $PLACEMENT_AUTH_STRATEGY
+    configure_auth_token_middleware $PLACEMENT_CONF placement $PLACEMENT_AUTH_CACHE_DIR
+    setup_logging $PLACEMENT_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
+    sudo install -d -o $STACK_USER $PLACEMENT_CONF_DIR
+    create_placement_conf
 
     if [[ "$WSGI_MODE" == "uwsgi" ]]; then
         write_uwsgi_config "$PLACEMENT_UWSGI_CONF" "$PLACEMENT_UWSGI" "/placement"
@@ -143,25 +140,28 @@
         "$placement_api_url"
 }
 
+# create_placement_cache_dir() - Create directories for keystone cache
+function create_placement_cache_dir {
+    # Create cache dir
+    sudo install -d -o $STACK_USER $PLACEMENT_AUTH_CACHE_DIR
+    rm -f $PLACEMENT_AUTH_CACHE_DIR/*
+}
+
 # init_placement() - Create service user and endpoints
-# If PLACEMENT_DB_ENABLED is true, create the separate placement db
-# using, for now, the api_db migrations.
 function init_placement {
-    if [ "$PLACEMENT_DB_ENABLED" != False ]; then
-        recreate_database placement
-        # Database migration will be handled when nova does an api_db sync
-        # TODO(cdent): When placement is extracted we'll do our own sync
-        # here.
-    fi
+    recreate_database placement
+    $PLACEMENT_BIN_DIR/placement-manage db sync
     create_placement_accounts
+    create_placement_cache_dir
 }
 
 # install_placement() - Collect source and prepare
 function install_placement {
     install_apache_wsgi
     # Install the openstackclient placement client plugin for CLI
-    # TODO(mriedem): Use pip_install_gr once osc-placement is in g-r.
-    pip_install osc-placement
+    pip_install_gr osc-placement
+    git_clone $PLACEMENT_REPO $PLACEMENT_DIR $PLACEMENT_BRANCH
+    setup_develop $PLACEMENT_DIR
 }
 
 # start_placement_api() - Start the API processes ahead of other things
diff --git a/roles/setup-devstack-source-dirs/README.rst b/roles/setup-devstack-source-dirs/README.rst
index 4ebf839..49d22c3 100644
--- a/roles/setup-devstack-source-dirs/README.rst
+++ b/roles/setup-devstack-source-dirs/README.rst
@@ -9,3 +9,8 @@
    :default: /opt/stack
 
    The devstack base directory.
+
+ .. zuul:rolevar:: devstack_sources_branch
+    :default: None
+
+    The target branch to be setup (where available).
diff --git a/roles/setup-devstack-source-dirs/tasks/main.yaml b/roles/setup-devstack-source-dirs/tasks/main.yaml
index e6bbae2..c196c37 100644
--- a/roles/setup-devstack-source-dirs/tasks/main.yaml
+++ b/roles/setup-devstack-source-dirs/tasks/main.yaml
@@ -12,6 +12,35 @@
   with_items: '{{ found_repos.files }}'
   become: yes
 
+- name: Setup refspec for repos into devstack working directory
+  shell:
+    # Copied almost "as-is" from devstack-gate setup-workspace function
+    # but removing the dependency on functions.sh
+    # TODO this should be rewritten as a python module.
+    cmd: |
+      cd {{ devstack_base_dir }}/{{ item.path | basename }}
+      base_branch={{ devstack_sources_branch }}
+      if git branch -a | grep "$base_branch" > /dev/null ; then
+          git checkout $base_branch
+      elif [[ "$base_branch" == stable/* ]]; then
+          # Look for an eol tag for the stable branch.
+          eol_tag=${base_branch#stable/}-eol
+          if git tag -l |grep $eol_tag >/dev/null; then
+              git checkout $eol_tag
+              git reset --hard $eol_tag
+              if ! git clean -x -f -d -q ; then
+                  sleep 1
+                  git clean -x -f -d -q
+              fi
+          fi
+      else
+          git checkout master
+      fi
+  args:
+    executable: /bin/bash
+  with_items: '{{ found_repos.files }}'
+  when: devstack_sources_branch is defined
+
 - name: Set ownership of repos
   file:
     path: '{{ devstack_base_dir }}'
diff --git a/setup.cfg b/setup.cfg
index fcd2b13..825d386 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -4,7 +4,7 @@
 description-file =
     README.rst
 author = OpenStack
-author-email = openstack-dev@lists.openstack.org
+author-email = openstack-discuss@lists.openstack.org
 home-page = https://docs.openstack.org/devstack/latest
 classifier =
     Intended Audience :: Developers
diff --git a/stack.sh b/stack.sh
index be3c4be..497c8bc 100755
--- a/stack.sh
+++ b/stack.sh
@@ -894,8 +894,6 @@
     stack_install_service neutron
 fi
 
-# Nova configuration is used by placement so we need to create nova.conf
-# first.
 if is_service_enabled nova; then
     # Compute service
     stack_install_service nova
diff --git a/stackrc b/stackrc
index 34bd677..746372d 100644
--- a/stackrc
+++ b/stackrc
@@ -298,6 +298,10 @@
 SWIFT_REPO=${SWIFT_REPO:-${GIT_BASE}/openstack/swift.git}
 SWIFT_BRANCH=${SWIFT_BRANCH:-$TARGET_BRANCH}
 
+# placement service
+PLACEMENT_REPO=${PLACEMENT_REPO:-${GIT_BASE}/openstack/placement.git}
+PLACEMENT_BRANCH=${PLACEMENT_BRANCH:-$TARGET_BRANCH}
+
 ##############
 #
 #  Testing Components