Merge "Add SERVICE_TOKEN to the sample local.conf"
diff --git a/HACKING.rst b/HACKING.rst
index 83455e3..d69bb49 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -17,7 +17,7 @@
 
 Contributing code to DevStack follows the usual OpenStack process as described
 in `How To Contribute`__ in the OpenStack wiki.  `DevStack's LaunchPad project`__
-contains the usual links for blueprints, bugs, tec.
+contains the usual links for blueprints, bugs, etc.
 
 __ contribute_
 .. _contribute: http://wiki.openstack.org/HowToContribute
diff --git a/files/apts/general b/files/apts/general
index f3cab59..d65cab3 100644
--- a/files/apts/general
+++ b/files/apts/general
@@ -24,3 +24,4 @@
 python2.7
 bc
 libyaml-dev
+libffi-dev
diff --git a/files/apts/glance b/files/apts/glance
index b5d8c77..15e09aa 100644
--- a/files/apts/glance
+++ b/files/apts/glance
@@ -1,4 +1,3 @@
-libffi-dev
 libmysqlclient-dev  # testonly
 libpq-dev           # testonly
 libssl-dev          # testonly
diff --git a/files/apts/nova b/files/apts/nova
index 38c99c7..e779849 100644
--- a/files/apts/nova
+++ b/files/apts/nova
@@ -1,5 +1,6 @@
 dnsmasq-base
 dnsmasq-utils # for dhcp_release
+conntrack
 kpartx
 parted
 iputils-arping
diff --git a/files/apts/swift b/files/apts/swift
index 080ecdb..fd51699 100644
--- a/files/apts/swift
+++ b/files/apts/swift
@@ -1,5 +1,4 @@
 curl
-libffi-dev
 memcached
 python-configobj
 python-coverage
diff --git a/files/rpms-suse/nova b/files/rpms-suse/nova
index 3e95724..7a1160e 100644
--- a/files/rpms-suse/nova
+++ b/files/rpms-suse/nova
@@ -1,6 +1,7 @@
 curl
 dnsmasq
 dnsmasq-utils # dist:opensuse-12.3,opensuse-13.1
+conntrack-tools
 ebtables
 gawk
 genisoimage # required for config_drive
diff --git a/files/rpms/general b/files/rpms/general
index a0074dd..74997a8 100644
--- a/files/rpms/general
+++ b/files/rpms/general
@@ -7,6 +7,7 @@
 openssh-server
 openssl
 openssl-devel # to rebuild pyOpenSSL if needed
+libffi-devel
 libxml2-devel
 libxslt-devel
 psmisc
diff --git a/files/rpms/glance b/files/rpms/glance
index fc07fa7..5a7f073 100644
--- a/files/rpms/glance
+++ b/files/rpms/glance
@@ -1,4 +1,3 @@
-libffi-devel
 libxml2-devel       # testonly
 libxslt-devel       # testonly
 mysql-devel         # testonly
diff --git a/files/rpms/nova b/files/rpms/nova
index e05d0d7..fa472a8 100644
--- a/files/rpms/nova
+++ b/files/rpms/nova
@@ -1,6 +1,7 @@
 MySQL-python
 curl
 dnsmasq-utils # for dhcp_release
+conntrack-tools
 ebtables
 gawk
 genisoimage # required for config_drive
diff --git a/files/rpms/swift b/files/rpms/swift
index 938d2c8..9ec4aab 100644
--- a/files/rpms/swift
+++ b/files/rpms/swift
@@ -1,5 +1,4 @@
 curl
-libffi-devel
 memcached
 python-configobj
 python-coverage
diff --git a/functions-common b/functions-common
index 9093952..4c9d1da 100644
--- a/functions-common
+++ b/functions-common
@@ -723,8 +723,13 @@
 }
 
 # Gets or creates user
-# Usage: get_or_create_user <username> <password> <project> <email>
+# Usage: get_or_create_user <username> <password> <project> [<email>]
 function get_or_create_user {
+    if [[ ! -z "$4" ]]; then
+        local EMAIL="--email=$4"
+    else
+        local EMAIL=""
+    fi
     # Gets user id
     USER_ID=$(
         # Gets user id
@@ -734,7 +739,7 @@
             $1 \
             --password "$2" \
             --project $3 \
-            --email $4 \
+            $EMAIL \
             -f value -c id
     )
     echo $USER_ID
@@ -988,7 +993,7 @@
 # Distro-agnostic package installer
 # install_package package [package ...]
 function update_package_repo {
-    if [[ "NO_UPDATE_REPOS" = "True" ]]; then
+    if [[ "$NO_UPDATE_REPOS" = "True" ]]; then
         return 0
     fi
 
diff --git a/lib/ceilometer b/lib/ceilometer
index 1540e3e..54d95c5 100644
--- a/lib/ceilometer
+++ b/lib/ceilometer
@@ -85,7 +85,7 @@
     # Ceilometer
     if [[ "$ENABLED_SERVICES" =~ "ceilometer-api" ]]; then
         CEILOMETER_USER=$(get_or_create_user "ceilometer" \
-            "$SERVICE_PASSWORD" $SERVICE_TENANT "ceilometer@example.com")
+            "$SERVICE_PASSWORD" $SERVICE_TENANT)
         get_or_add_user_role $ADMIN_ROLE $CEILOMETER_USER $SERVICE_TENANT
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
@@ -113,16 +113,8 @@
     fi
 }
 
-# configure_ceilometerclient() - Set config files, create data dirs, etc
-function configure_ceilometerclient {
-    setup_develop $CEILOMETERCLIENT_DIR
-    sudo install -D -m 0644 -o $STACK_USER {$CEILOMETERCLIENT_DIR/tools/,/etc/bash_completion.d/}ceilometer.bash_completion
-}
-
 # configure_ceilometer() - Set config files, create data dirs, etc
 function configure_ceilometer {
-    setup_develop $CEILOMETER_DIR
-
     [ ! -d $CEILOMETER_CONF_DIR ] && sudo mkdir -m 755 -p $CEILOMETER_CONF_DIR
     sudo chown $STACK_USER $CEILOMETER_CONF_DIR
 
@@ -218,11 +210,15 @@
 # install_ceilometer() - Collect source and prepare
 function install_ceilometer {
     git_clone $CEILOMETER_REPO $CEILOMETER_DIR $CEILOMETER_BRANCH
+    setup_develop $CEILOMETER_DIR
+
 }
 
 # install_ceilometerclient() - Collect source and prepare
 function install_ceilometerclient {
     git_clone $CEILOMETERCLIENT_REPO $CEILOMETERCLIENT_DIR $CEILOMETERCLIENT_BRANCH
+    setup_develop $CEILOMETERCLIENT_DIR
+    sudo install -D -m 0644 -o $STACK_USER {$CEILOMETERCLIENT_DIR/tools/,/etc/bash_completion.d/}ceilometer.bash_completion
 }
 
 # start_ceilometer() - Start running processes, including screen
diff --git a/lib/cinder b/lib/cinder
index 3965687..a51e4a0 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -323,7 +323,7 @@
     if [[ "$ENABLED_SERVICES" =~ "c-api" ]]; then
 
         CINDER_USER=$(get_or_create_user "cinder" \
-            "$SERVICE_PASSWORD" $SERVICE_TENANT "cinder@example.com")
+            "$SERVICE_PASSWORD" $SERVICE_TENANT)
         get_or_add_user_role $ADMIN_ROLE $CINDER_USER $SERVICE_TENANT
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
diff --git a/lib/glance b/lib/glance
index 475bb48..92577d9 100644
--- a/lib/glance
+++ b/lib/glance
@@ -166,7 +166,7 @@
     if is_service_enabled g-api; then
 
         GLANCE_USER=$(get_or_create_user "glance" \
-            "$SERVICE_PASSWORD" $SERVICE_TENANT_NAME "glance@example.com")
+            "$SERVICE_PASSWORD" $SERVICE_TENANT_NAME)
         get_or_add_user_role service $GLANCE_USER $SERVICE_TENANT_NAME
 
         # required for swift access
diff --git a/lib/heat b/lib/heat
index afed52b..510b683 100644
--- a/lib/heat
+++ b/lib/heat
@@ -217,7 +217,7 @@
     ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
 
     HEAT_USER=$(get_or_create_user "heat" \
-        "$SERVICE_PASSWORD" $SERVICE_TENANT "heat@example.com")
+        "$SERVICE_PASSWORD" $SERVICE_TENANT)
     get_or_add_user_role $ADMIN_ROLE $HEAT_USER $SERVICE_TENANT
 
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
diff --git a/lib/ironic b/lib/ironic
index ef136bc..08ac278 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -221,7 +221,7 @@
         # Get ironic user if exists
 
         IRONIC_USER=$(get_or_create_user "ironic" \
-            "$SERVICE_PASSWORD" $SERVICE_TENANT "ironic@example.com")
+            "$SERVICE_PASSWORD" $SERVICE_TENANT)
         get_or_add_user_role $ADMIN_ROLE $IRONIC_USER $SERVICE_TENANT
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
diff --git a/lib/keystone b/lib/keystone
index 4e94bad..547646a 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -330,7 +330,7 @@
     # admin
     ADMIN_TENANT=$(get_or_create_project "admin")
     ADMIN_USER=$(get_or_create_user "admin" \
-        "$ADMIN_PASSWORD" "$ADMIN_TENANT" "admin@example.com")
+        "$ADMIN_PASSWORD" "$ADMIN_TENANT")
     ADMIN_ROLE=$(get_or_create_role "admin")
     get_or_add_user_role $ADMIN_ROLE $ADMIN_USER $ADMIN_TENANT
 
@@ -496,6 +496,9 @@
     _cleanup_keystone_apache_wsgi
 }
 
+function is_keystone_enabled {
+    return is_service_enabled key
+}
 
 # Restore xtrace
 $XTRACE
diff --git a/lib/marconi b/lib/marconi
index d7822c9..063ed3d 100644
--- a/lib/marconi
+++ b/lib/marconi
@@ -179,7 +179,7 @@
     ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
 
     MARCONI_USER=$(get_or_create_user "marconi" \
-        "$SERVICE_PASSWORD" $SERVICE_TENANT "marconi@example.com")
+        "$SERVICE_PASSWORD" $SERVICE_TENANT)
     get_or_add_user_role $ADMIN_ROLE $MARCONI_USER $SERVICE_TENANT
 
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
diff --git a/lib/neutron b/lib/neutron
index 8b883b1..98ae3ac 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -143,6 +143,17 @@
     Q_RR_COMMAND="sudo $NEUTRON_ROOTWRAP $Q_RR_CONF_FILE"
 fi
 
+
+# Distributed Virtual Router (DVR) configuration
+# Can be:
+#     legacy   - No DVR functionality
+#     dvr_snat - Controller or single node DVR
+#     dvr      - Compute node in multi-node DVR
+Q_DVR_MODE=${Q_DVR_MODE:-legacy}
+if [[ "$Q_DVR_MODE" != "legacy" ]]; then
+    Q_ML2_PLUGIN_MECHANISM_DRIVERS=openvswitch,linuxbridge,l2population
+fi
+
 # Provider Network Configurations
 # --------------------------------
 
@@ -303,6 +314,10 @@
     if is_service_enabled q-meta; then
         _configure_neutron_metadata_agent
     fi
+
+    if [[ "$Q_DVR_MODE" != "legacy" ]]; then
+        _configure_dvr
+    fi
     if is_service_enabled ceilometer; then
         _configure_neutron_ceilometer_notifications
     fi
@@ -362,7 +377,7 @@
     if [[ "$ENABLED_SERVICES" =~ "q-svc" ]]; then
 
         NEUTRON_USER=$(get_or_create_user "neutron" \
-            "$SERVICE_PASSWORD" $SERVICE_TENANT "neutron@example.com")
+            "$SERVICE_PASSWORD" $SERVICE_TENANT)
         get_or_add_user_role $ADMIN_ROLE $NEUTRON_USER $SERVICE_TENANT
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
@@ -574,7 +589,7 @@
     fi
 
     # delete all namespaces created by neutron
-    for ns in $(sudo ip netns list | grep -o -E '(qdhcp|qrouter|qlbaas)-[0-9a-f-]*'); do
+    for ns in $(sudo ip netns list | grep -o -E '(qdhcp|qrouter|qlbaas|fip|snat)-[0-9a-f-]*'); do
         sudo ip netns delete ${ns}
     done
 }
@@ -756,6 +771,12 @@
     neutron_vpn_configure_common
 }
 
+function _configure_dvr {
+    iniset $NEUTRON_CONF DEFAULT router_distributed True
+    iniset $Q_L3_CONF_FILE DEFAULT agent_mode $Q_DVR_MODE
+}
+
+
 # _configure_neutron_plugin_agent() - Set config files for neutron plugin agent
 # It is called when q-agt is enabled.
 function _configure_neutron_plugin_agent {
diff --git a/lib/neutron_plugins/ml2 b/lib/neutron_plugins/ml2
index 8e131bb..4cf484e 100644
--- a/lib/neutron_plugins/ml2
+++ b/lib/neutron_plugins/ml2
@@ -112,6 +112,12 @@
     populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_type_vxlan $Q_ML2_PLUGIN_VXLAN_TYPE_OPTIONS
 
     populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_type_vlan $Q_ML2_PLUGIN_VLAN_TYPE_OPTIONS
+
+    if [[ "$Q_DVR_MODE" != "legacy" ]]; then
+        populate_ml2_config /$Q_PLUGIN_CONF_FILE agent l2_population=True
+        populate_ml2_config /$Q_PLUGIN_CONF_FILE agent tunnel_types=vxlan
+        populate_ml2_config /$Q_PLUGIN_CONF_FILE agent enable_distributed_routing=True
+    fi
 }
 
 function has_neutron_plugin_security_group {
diff --git a/lib/nova b/lib/nova
index ebdb6b4..5d879db 100644
--- a/lib/nova
+++ b/lib/nova
@@ -335,7 +335,7 @@
     if [[ "$ENABLED_SERVICES" =~ "n-api" ]]; then
 
         NOVA_USER=$(get_or_create_user "nova" \
-            "$SERVICE_PASSWORD" $SERVICE_TENANT "nova@example.com")
+            "$SERVICE_PASSWORD" $SERVICE_TENANT)
         get_or_add_user_role $ADMIN_ROLE $NOVA_USER $SERVICE_TENANT
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
diff --git a/lib/rpc_backend b/lib/rpc_backend
index e922daa..a62d4e7 100644
--- a/lib/rpc_backend
+++ b/lib/rpc_backend
@@ -94,11 +94,7 @@
 function install_rpc_backend {
     if is_service_enabled rabbit; then
         # Install rabbitmq-server
-        # the temp file is necessary due to LP: #878600
-        tfile=$(mktemp)
-        install_package rabbitmq-server > "$tfile" 2>&1
-        cat "$tfile"
-        rm -f "$tfile"
+        install_package rabbitmq-server
     elif is_service_enabled qpid; then
         if is_fedora; then
             install_package qpid-cpp-server
diff --git a/lib/sahara b/lib/sahara
index 0cc2fe9..70feacd 100644
--- a/lib/sahara
+++ b/lib/sahara
@@ -61,7 +61,7 @@
     ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
 
     SAHARA_USER=$(get_or_create_user "sahara" \
-        "$SERVICE_PASSWORD" $SERVICE_TENANT "sahara@example.com")
+        "$SERVICE_PASSWORD" $SERVICE_TENANT)
     get_or_add_user_role $ADMIN_ROLE $SAHARA_USER $SERVICE_TENANT
 
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
diff --git a/lib/swift b/lib/swift
index 2b161c3..84304d3 100644
--- a/lib/swift
+++ b/lib/swift
@@ -550,7 +550,7 @@
     ADMIN_ROLE=$(openstack role list | awk "/ admin / { print \$2 }")
 
     SWIFT_USER=$(get_or_create_user "swift" \
-        "$SERVICE_PASSWORD" $SERVICE_TENANT "swift@example.com")
+        "$SERVICE_PASSWORD" $SERVICE_TENANT)
     get_or_add_user_role $ADMIN_ROLE $SWIFT_USER $SERVICE_TENANT
 
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
diff --git a/lib/tls b/lib/tls
index a84bb76..e58e513 100644
--- a/lib/tls
+++ b/lib/tls
@@ -323,7 +323,8 @@
 #
 # Uses global ``SSL_ENABLED_SERVICES``
 function is_ssl_enabled_service {
-    services=$@
+    local services=$@
+    local service=""
     for service in ${services}; do
         [[ ,${SSL_ENABLED_SERVICES}, =~ ,${service}, ]] && return 0
     done
diff --git a/lib/trove b/lib/trove
index 2552745..2a54336 100644
--- a/lib/trove
+++ b/lib/trove
@@ -83,7 +83,7 @@
     if [[ "$ENABLED_SERVICES" =~ "trove" ]]; then
 
         TROVE_USER=$(get_or_create_user "trove" \
-            "$SERVICE_PASSWORD" $SERVICE_TENANT "trove@example.com")
+            "$SERVICE_PASSWORD" $SERVICE_TENANT)
         get_or_add_user_role $SERVICE_ROLE $TROVE_USER $SERVICE_TENANT
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
diff --git a/stack.sh b/stack.sh
index 94b90d1..cdfa3da 100755
--- a/stack.sh
+++ b/stack.sh
@@ -802,7 +802,6 @@
     install_ceilometer
     echo_summary "Configuring Ceilometer"
     configure_ceilometer
-    configure_ceilometerclient
 fi
 
 if is_service_enabled heat; then