Merge "Implement Ceph backend for Glance / Cinder / Nova"
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/docs/source/faq.html b/docs/source/faq.html
index 4867eb4..bfac1dc 100644
--- a/docs/source/faq.html
+++ b/docs/source/faq.html
@@ -18,7 +18,7 @@
       body { padding-top: 60px; }
       dd { padding: 10px; }
     </style>
-    
+
     <!-- Le javascripts -->
     <script src="assets/js/jquery-1.7.1.min.js" type="text/javascript" charset="utf-8"></script>
     <script src="assets/js/bootstrap.js" type="text/javascript" charset="utf-8"></script>
@@ -42,7 +42,7 @@
     </div>
 
     <div class="container" id="home">
-      
+
       <section id="faq" class="span12">
 
         <div class='row pull-left'>
@@ -68,16 +68,16 @@
 
             <dt>Q: Why a shell script, why not chef/puppet/...</dt>
             <dd>A: The script is meant to be read by humans (as well as ran by computers); it is the primary documentation after all.  Using a recipe system requires everyone to agree and understand chef or puppet.</dd>
-    
+
             <dt>Q: Why not use Crowbar?</dt>
             <dd>A: DevStack is optimized for documentation &amp; developers.  As some of us use <a href="https://github.com/dellcloudedge/crowbar">Crowbar</a> for production deployments, we hope developers documenting how they setup systems for new features supports projects like Crowbar.</dd>
-    
+
             <dt>Q: I'd like to help!</dt>
-            <dd>A: That isn't a question, but please do!  The source for DevStack is <a href="http://github.com/openstack-dev/devstack">github</a> and bug reports go to <a href="http://bugs.launchpad.net/devstack/">LaunchPad</a>.  Contributions follow the usual process as described in the <a href="http://wiki.openstack.org/HowToContribute">OpenStack wiki</a> even though DevStack is not an official OpenStack project.  This site is housed in the CloudBuilder's <a href="http://github.com/cloudbuilders/devstack">github</a> in the gh-pages branch.</dd>
-    
+            <dd>A: That isn't a question, but please do!  The source for DevStack is <a href="http://github.com/openstack-dev/devstack">github</a> and bug reports go to <a href="http://bugs.launchpad.net/devstack/">LaunchPad</a>.  Contributions follow the usual process as described in the <a href="http://wiki.openstack.org/HowToContribute">OpenStack wiki</a>. DevStack is not a core project but a gating project and therefore an official OpenStack project. This site is housed in the CloudBuilder's <a href="http://github.com/cloudbuilders/devstack">github</a> in the gh-pages branch.</dd>
+
             <dt>Q: Why not use packages?</dt>
             <dd>A: Unlike packages, DevStack leaves your cloud ready to develop - checkouts of the code and services running in screen. However, many people are doing the hard work of packaging and recipes for production deployments.  We hope this script serves as a way to communicate configuration changes between developers and packagers.</dd>
-    
+
             <dt>Q: Why isn't $MY_FAVORITE_DISTRO supported?</dt>
             <dd>A: DevStack is meant for developers and those who want to see how OpenStack really works.  DevStack is known to run on the distro/release combinations listed in <code>README.md</code>.  DevStack is only supported on releases other than those documented in <code>README.md</code> on a best-effort basis.</dd>
 
@@ -96,7 +96,7 @@
           <dl class='pull-left'>
             <dt>Q: Can DevStack handle a multi-node installation?</dt>
             <dd>A: Indirectly, yes.  You run DevStack on each node with the appropriate configuration in <code>local.conf</code>.  The primary considerations are turning off the services not required on the secondary nodes, making sure the passwords match and setting the various API URLs to the right place.</dd>
-    
+
             <dt>Q: How can I document the environment that DevStack is using?</dt>
             <dd>A: DevStack includes a script (<code>tools/info.sh</code>) that gathers the versions of the relevant installed apt packages, pip packages and git repos.  This is a good way to verify what Python modules are installed.</dd>
 
diff --git a/exercises/trove.sh b/exercises/trove.sh
index d48d5fe..053f872 100755
--- a/exercises/trove.sh
+++ b/exercises/trove.sh
@@ -35,8 +35,12 @@
 
 is_service_enabled trove || exit 55
 
-# can we get a list versions
-curl http://$SERVICE_HOST:8779/ 2>/dev/null | grep -q 'versions' || die $LINENO "Trove API not functioning!"
+# can try to get datastore id
+DSTORE_ID=$(trove datastore-list | tail -n +4 |head -3 | get_field 1)
+die_if_not_set $LINENO  DSTORE_ID "Trove API not functioning!"
+
+DV_ID=$(trove datastore-version-list $DSTORE_ID | tail -n +4 | get_field 1)
+die_if_not_set $LINENO DV_ID "Trove API not functioning!"
 
 set +o xtrace
 echo "*********************************************************************"
diff --git a/files/apache-keystone.template b/files/apache-keystone.template
index 919452a..805e7b8 100644
--- a/files/apache-keystone.template
+++ b/files/apache-keystone.template
@@ -20,3 +20,7 @@
     LogLevel debug
     CustomLog /var/log/%APACHE_NAME%/access.log combined
 </VirtualHost>
+
+# Workaround for missing path on RHEL6, see
+#  https://bugzilla.redhat.com/show_bug.cgi?id=1121019
+WSGISocketPrefix /var/run/%APACHE_NAME%
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/neutron b/files/rpms/neutron
index 9fafecb..15ed973 100644
--- a/files/rpms/neutron
+++ b/files/rpms/neutron
@@ -1,4 +1,5 @@
 MySQL-python
+dnsmasq # for q-dhcp
 dnsmasq-utils # for dhcp_release
 ebtables
 iptables
diff --git a/files/rpms/nova b/files/rpms/nova
index e05d0d7..6097991 100644
--- a/files/rpms/nova
+++ b/files/rpms/nova
@@ -1,6 +1,8 @@
 MySQL-python
 curl
+dnsmasq # for nova-network
 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 44225ab..2df5e1d 100644
--- a/functions-common
+++ b/functions-common
@@ -435,7 +435,9 @@
         else
             DISTRO="sle${os_RELEASE}sp${os_UPDATE}"
         fi
-    elif [[ "$os_VENDOR" =~ (Red Hat) || "$os_VENDOR" =~ (CentOS) ]]; then
+    elif [[ "$os_VENDOR" =~ (Red Hat) || \
+        "$os_VENDOR" =~ (CentOS) || \
+        "$os_VENDOR" =~ (OracleServer) ]]; then
         # Drop the . release as we assume it's compatible
         DISTRO="rhel${os_RELEASE::1}"
     elif [[ "$os_VENDOR" =~ (XenServer) ]]; then
@@ -463,7 +465,8 @@
         GetOSVersion
     fi
 
-    [ "$os_VENDOR" = "Fedora" ] || [ "$os_VENDOR" = "Red Hat" ] || [ "$os_VENDOR" = "CentOS" ]
+    [ "$os_VENDOR" = "Fedora" ] || [ "$os_VENDOR" = "Red Hat" ] || \
+        [ "$os_VENDOR" = "CentOS" ] || [ "$os_VENDOR" = "OracleServer" ]
 }
 
 
@@ -497,6 +500,7 @@
 # ``get_release_name_from_branch branch-name``
 function get_release_name_from_branch {
     local branch=$1
+
     if [[ $branch =~ "stable/" ]]; then
         echo ${branch#*/}
     else
@@ -507,72 +511,73 @@
 # git clone only if directory doesn't exist already.  Since ``DEST`` might not
 # be owned by the installation user, we create the directory and change the
 # ownership to the proper user.
-# Set global RECLONE=yes to simulate a clone when dest-dir exists
-# Set global ERROR_ON_CLONE=True to abort execution with an error if the git repo
+# Set global ``RECLONE=yes`` to simulate a clone when dest-dir exists
+# Set global ``ERROR_ON_CLONE=True`` to abort execution with an error if the git repo
 # does not exist (default is False, meaning the repo will be cloned).
-# Uses global ``OFFLINE``
+# Uses globals ``ERROR_ON_CLONE``, ``OFFLINE``, ``RECLONE``
 # git_clone remote dest-dir branch
 function git_clone {
-    GIT_REMOTE=$1
-    GIT_DEST=$2
-    GIT_REF=$3
+    local git_remote=$1
+    local git_dest=$2
+    local git_ref=$3
+    local orig_dir=$(pwd)
+
     RECLONE=$(trueorfalse False $RECLONE)
-    local orig_dir=`pwd`
 
     if [[ "$OFFLINE" = "True" ]]; then
         echo "Running in offline mode, clones already exist"
         # print out the results so we know what change was used in the logs
-        cd $GIT_DEST
+        cd $git_dest
         git show --oneline | head -1
         cd $orig_dir
         return
     fi
 
-    if echo $GIT_REF | egrep -q "^refs"; then
+    if echo $git_ref | egrep -q "^refs"; then
         # If our branch name is a gerrit style refs/changes/...
-        if [[ ! -d $GIT_DEST ]]; then
+        if [[ ! -d $git_dest ]]; then
             [[ "$ERROR_ON_CLONE" = "True" ]] && \
                 die $LINENO "Cloning not allowed in this configuration"
-            git_timed clone $GIT_REMOTE $GIT_DEST
+            git_timed clone $git_remote $git_dest
         fi
-        cd $GIT_DEST
-        git_timed fetch $GIT_REMOTE $GIT_REF && git checkout FETCH_HEAD
+        cd $git_dest
+        git_timed fetch $git_remote $git_ref && git checkout FETCH_HEAD
     else
         # do a full clone only if the directory doesn't exist
-        if [[ ! -d $GIT_DEST ]]; then
+        if [[ ! -d $git_dest ]]; then
             [[ "$ERROR_ON_CLONE" = "True" ]] && \
                 die $LINENO "Cloning not allowed in this configuration"
-            git_timed clone $GIT_REMOTE $GIT_DEST
-            cd $GIT_DEST
+            git_timed clone $git_remote $git_dest
+            cd $git_dest
             # This checkout syntax works for both branches and tags
-            git checkout $GIT_REF
+            git checkout $git_ref
         elif [[ "$RECLONE" = "True" ]]; then
             # if it does exist then simulate what clone does if asked to RECLONE
-            cd $GIT_DEST
+            cd $git_dest
             # set the url to pull from and fetch
-            git remote set-url origin $GIT_REMOTE
+            git remote set-url origin $git_remote
             git_timed fetch origin
             # remove the existing ignored files (like pyc) as they cause breakage
             # (due to the py files having older timestamps than our pyc, so python
             # thinks the pyc files are correct using them)
-            find $GIT_DEST -name '*.pyc' -delete
+            find $git_dest -name '*.pyc' -delete
 
-            # handle GIT_REF accordingly to type (tag, branch)
-            if [[ -n "`git show-ref refs/tags/$GIT_REF`" ]]; then
-                git_update_tag $GIT_REF
-            elif [[ -n "`git show-ref refs/heads/$GIT_REF`" ]]; then
-                git_update_branch $GIT_REF
-            elif [[ -n "`git show-ref refs/remotes/origin/$GIT_REF`" ]]; then
-                git_update_remote_branch $GIT_REF
+            # handle git_ref accordingly to type (tag, branch)
+            if [[ -n "`git show-ref refs/tags/$git_ref`" ]]; then
+                git_update_tag $git_ref
+            elif [[ -n "`git show-ref refs/heads/$git_ref`" ]]; then
+                git_update_branch $git_ref
+            elif [[ -n "`git show-ref refs/remotes/origin/$git_ref`" ]]; then
+                git_update_remote_branch $git_ref
             else
-                die $LINENO "$GIT_REF is neither branch nor tag"
+                die $LINENO "$git_ref is neither branch nor tag"
             fi
 
         fi
     fi
 
     # print out the results so we know what change was used in the logs
-    cd $GIT_DEST
+    cd $git_dest
     git show --oneline | head -1
     cd $orig_dir
 }
@@ -611,35 +616,32 @@
 # git update using reference as a branch.
 # git_update_branch ref
 function git_update_branch {
+    local git_branch=$1
 
-    GIT_BRANCH=$1
-
-    git checkout -f origin/$GIT_BRANCH
+    git checkout -f origin/$git_branch
     # a local branch might not exist
-    git branch -D $GIT_BRANCH || true
-    git checkout -b $GIT_BRANCH
+    git branch -D $git_branch || true
+    git checkout -b $git_branch
 }
 
 # git update using reference as a branch.
 # git_update_remote_branch ref
 function git_update_remote_branch {
+    local git_branch=$1
 
-    GIT_BRANCH=$1
-
-    git checkout -b $GIT_BRANCH -t origin/$GIT_BRANCH
+    git checkout -b $git_branch -t origin/$git_branch
 }
 
 # git update using reference as a tag. Be careful editing source at that repo
 # as working copy will be in a detached mode
 # git_update_tag ref
 function git_update_tag {
+    local git_tag=$1
 
-    GIT_TAG=$1
-
-    git tag -d $GIT_TAG
+    git tag -d $git_tag
     # fetching given tag only
-    git_timed fetch origin tag $GIT_TAG
-    git checkout -f $GIT_TAG
+    git_timed fetch origin tag $git_tag
+    git checkout -f $git_tag
 }
 
 
@@ -720,8 +722,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
@@ -731,7 +738,7 @@
             $1 \
             --password "$2" \
             --project $3 \
-            --email $4 \
+            $EMAIL \
             -f value -c id
     )
     echo $USER_ID
@@ -985,7 +992,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/apache b/lib/apache
index c0d32df..f4f82a1 100644
--- a/lib/apache
+++ b/lib/apache
@@ -150,7 +150,12 @@
 
 # restart_apache_server
 function restart_apache_server {
-    restart_service $APACHE_NAME
+    # Apache can be slow to stop, doing an explicit stop, sleep, start helps
+    # to mitigate issues where apache will claim a port it's listening on is
+    # still in use and fail to start.
+    stop_service $APACHE_NAME
+    sleep 3
+    start_service $APACHE_NAME
 }
 
 # Restore xtrace
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 ce2a5c9..a51e4a0 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -246,13 +246,13 @@
                 configure_cinder_backend_${BE_TYPE} ${BE_NAME}
             fi
             if [[ -z "$default_type" ]]; then
-                default_type=$BE_TYPE}
+                default_type=$BE_TYPE
             fi
             enabled_backends+=$BE_NAME,
         done
         iniset $CINDER_CONF DEFAULT enabled_backends ${enabled_backends%,*}
         if [[ -n "$default_type" ]]; then
-            iniset $CINDER_CONF DEFAULT default_volume_type ${enabled_backends%,*}
+            iniset $CINDER_CONF DEFAULT default_volume_type ${default_type}
         fi
     fi
 
@@ -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/infra b/lib/infra
index e2f7dad..e18c66e 100644
--- a/lib/infra
+++ b/lib/infra
@@ -10,7 +10,6 @@
 
 # ``stack.sh`` calls the entry points in this order:
 #
-# - unfubar_setuptools
 # - install_infra
 
 # Save trace setting
@@ -26,19 +25,6 @@
 # Entry Points
 # ------------
 
-# unfubar_setuptools() - Unbreak the giant mess that is the current state of setuptools
-function unfubar_setuptools {
-    # this is a giant game of who's on first, but it does consistently work
-    # there is hope that upstream python packaging fixes this in the future
-    echo_summary "Unbreaking setuptools"
-    pip_install -U setuptools
-    pip_install -U pip
-    uninstall_package python-setuptools
-    pip_install -U setuptools
-    pip_install -U pip
-}
-
-
 # install_infra() - Collect source and prepare
 function install_infra {
     # bring down global requirements
diff --git a/lib/ironic b/lib/ironic
index c24780f..b56abcb 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -53,12 +53,7 @@
 IRONIC_VM_SSH_ADDRESS=${IRONIC_VM_SSH_ADDRESS:-$HOST_IP}
 IRONIC_VM_COUNT=${IRONIC_VM_COUNT:-1}
 IRONIC_VM_SPECS_CPU=${IRONIC_VM_SPECS_CPU:-1}
-# NOTE(adam_g): Kernels 3.12 and newer user tmpfs by default for initramfs.
-#               DIB produced ramdisks tend to be ~250MB but tmpfs will only allow
-#               use of 50% of available memory before ENOSPC.  Set minimum 1GB
-#               for nodes to avoid (LP: #1311987) and ensure consistency across
-#               older and newer kernels.
-IRONIC_VM_SPECS_RAM=${IRONIC_VM_SPECS_RAM:-1024}
+IRONIC_VM_SPECS_RAM=${IRONIC_VM_SPECS_RAM:-512}
 IRONIC_VM_SPECS_DISK=${IRONIC_VM_SPECS_DISK:-10}
 IRONIC_VM_EPHEMERAL_DISK=${IRONIC_VM_EPHEMERAL_DISK:-0}
 IRONIC_VM_EMULATOR=${IRONIC_VM_EMULATOR:-/usr/bin/qemu-system-x86_64}
@@ -115,6 +110,7 @@
 function install_ironicclient {
     git_clone $IRONICCLIENT_REPO $IRONICCLIENT_DIR $IRONICCLIENT_BRANCH
     setup_develop $IRONICCLIENT_DIR
+    sudo install -D -m 0644 -o $STACK_USER {$IRONICCLIENT_DIR/tools/,/etc/bash_completion.d/}ironic.bash_completion
 }
 
 # cleanup_ironic() - Remove residual data files, anything left over from previous
@@ -226,7 +222,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 6039872..ff4b3c4 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -85,6 +85,8 @@
 NEUTRON_CONF=$NEUTRON_CONF_DIR/neutron.conf
 export NEUTRON_TEST_CONFIG_FILE=${NEUTRON_TEST_CONFIG_FILE:-"$NEUTRON_CONF_DIR/debug.ini"}
 
+# Default name for Neutron database
+Q_DB_NAME=${Q_DB_NAME:-neutron}
 # Default Neutron Plugin
 Q_PLUGIN=${Q_PLUGIN:-ml2}
 # Default Neutron Port
@@ -143,6 +145,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
 # --------------------------------
 
@@ -203,6 +216,13 @@
 # Example: ``LB_PHYSICAL_INTERFACE=eth1``
 LB_PHYSICAL_INTERFACE=${LB_PHYSICAL_INTERFACE:-}
 
+# When Neutron tunnels are enabled it is needed to specify the
+# IP address of the end point in the local server. This IP is set
+# by default to the same IP address that the HOST IP.
+# This variable can be used to specify a different end point IP address
+# Example: ``TUNNEL_ENDPOINT_IP=1.1.1.1``
+TUNNEL_ENDPOINT_IP=${TUNNEL_ENDPOINT_IP:-$HOST_IP}
+
 # With the openvswitch plugin, set to True in ``localrc`` to enable
 # provider GRE tunnels when ``ENABLE_TENANT_TUNNELS`` is False.
 #
@@ -297,6 +317,13 @@
         _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
+
     _configure_neutron_debug_command
 }
 
@@ -352,7 +379,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
@@ -361,9 +388,9 @@
                 "network" "Neutron Service")
             get_or_create_endpoint $NEUTRON_SERVICE \
                 "$REGION_NAME" \
-                "http://$SERVICE_HOST:9696/" \
-                "http://$SERVICE_HOST:9696/" \
-                "http://$SERVICE_HOST:9696/"
+                "http://$SERVICE_HOST:$Q_PORT/" \
+                "http://$SERVICE_HOST:$Q_PORT/" \
+                "http://$SERVICE_HOST:$Q_PORT/"
         fi
     fi
 }
@@ -564,7 +591,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
 }
@@ -660,14 +687,6 @@
     iniset $Q_DHCP_CONF_FILE DEFAULT use_namespaces $Q_USE_NAMESPACE
     iniset $Q_DHCP_CONF_FILE DEFAULT root_helper "$Q_RR_COMMAND"
 
-    # Define extra "DEFAULT" configuration options when q-dhcp is configured by
-    # defining the array ``Q_DHCP_EXTRA_DEFAULT_OPTS``.
-    # For Example: ``Q_DHCP_EXTRA_DEFAULT_OPTS=(foo=true bar=2)``
-    for I in "${Q_DHCP_EXTRA_DEFAULT_OPTS[@]}"; do
-        # Replace the first '=' with ' ' for iniset syntax
-        iniset $Q_DHCP_CONF_FILE DEFAULT ${I/=/ }
-    done
-
     _neutron_setup_interface_driver $Q_DHCP_CONF_FILE
 
     neutron_plugin_configure_dhcp_agent
@@ -722,6 +741,10 @@
 
 }
 
+function _configure_neutron_ceilometer_notifications {
+    iniset $NEUTRON_CONF DEFAULT notification_driver neutron.openstack.common.notifier.rpc_notifier
+}
+
 function _configure_neutron_lbaas {
     neutron_agent_lbaas_configure_common
     neutron_agent_lbaas_configure_agent
@@ -742,6 +765,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 {
@@ -779,14 +808,6 @@
     iniset $NEUTRON_CONF DEFAULT auth_strategy $Q_AUTH_STRATEGY
     _neutron_setup_keystone $NEUTRON_CONF keystone_authtoken
 
-    # Define extra "DEFAULT" configuration options when q-svc is configured by
-    # defining the array ``Q_SRV_EXTRA_DEFAULT_OPTS``.
-    # For Example: ``Q_SRV_EXTRA_DEFAULT_OPTS=(foo=true bar=2)``
-    for I in "${Q_SRV_EXTRA_DEFAULT_OPTS[@]}"; do
-        # Replace the first '=' with ' ' for iniset syntax
-        iniset $NEUTRON_CONF DEFAULT ${I/=/ }
-    done
-
     # Configuration for neutron notifations to nova.
     iniset $NEUTRON_CONF DEFAULT notify_nova_on_port_status_changes $Q_NOTIFY_NOVA_PORT_STATUS_CHANGES
     iniset $NEUTRON_CONF DEFAULT notify_nova_on_port_data_changes $Q_NOTIFY_NOVA_PORT_DATA_CHANGES
diff --git a/lib/neutron_plugins/README.md b/lib/neutron_plugins/README.md
index be8fd96..7192a05 100644
--- a/lib/neutron_plugins/README.md
+++ b/lib/neutron_plugins/README.md
@@ -25,7 +25,7 @@
   install_package bridge-utils
 * ``neutron_plugin_configure_common`` :
   set plugin-specific variables, ``Q_PLUGIN_CONF_PATH``, ``Q_PLUGIN_CONF_FILENAME``,
-  ``Q_DB_NAME``, ``Q_PLUGIN_CLASS``
+  ``Q_PLUGIN_CLASS``
 * ``neutron_plugin_configure_debug_command``
 * ``neutron_plugin_configure_dhcp_agent``
 * ``neutron_plugin_configure_l3_agent``
diff --git a/lib/neutron_plugins/bigswitch_floodlight b/lib/neutron_plugins/bigswitch_floodlight
index efdd9ef..9e84f2e 100644
--- a/lib/neutron_plugins/bigswitch_floodlight
+++ b/lib/neutron_plugins/bigswitch_floodlight
@@ -19,7 +19,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/bigswitch
     Q_PLUGIN_CONF_FILENAME=restproxy.ini
-    Q_DB_NAME="restproxy_neutron"
     Q_PLUGIN_CLASS="neutron.plugins.bigswitch.plugin.NeutronRestProxyV2"
     BS_FL_CONTROLLERS_PORT=${BS_FL_CONTROLLERS_PORT:-localhost:80}
     BS_FL_CONTROLLER_TIMEOUT=${BS_FL_CONTROLLER_TIMEOUT:-10}
diff --git a/lib/neutron_plugins/brocade b/lib/neutron_plugins/brocade
index e4cc754..511fb71 100644
--- a/lib/neutron_plugins/brocade
+++ b/lib/neutron_plugins/brocade
@@ -20,7 +20,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/brocade
     Q_PLUGIN_CONF_FILENAME=brocade.ini
-    Q_DB_NAME="brcd_neutron"
     Q_PLUGIN_CLASS="neutron.plugins.brocade.NeutronPlugin.BrocadePluginV2"
 }
 
diff --git a/lib/neutron_plugins/cisco b/lib/neutron_plugins/cisco
index dccf400..da90ee3 100644
--- a/lib/neutron_plugins/cisco
+++ b/lib/neutron_plugins/cisco
@@ -197,7 +197,6 @@
         Q_PLUGIN_CONF_FILENAME=cisco_plugins.ini
     fi
     Q_PLUGIN_CLASS="neutron.plugins.cisco.network_plugin.PluginV2"
-    Q_DB_NAME=cisco_neutron
 }
 
 function neutron_plugin_configure_debug_command {
diff --git a/lib/neutron_plugins/embrane b/lib/neutron_plugins/embrane
index cce108a..7dafdc0 100644
--- a/lib/neutron_plugins/embrane
+++ b/lib/neutron_plugins/embrane
@@ -18,7 +18,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/embrane
     Q_PLUGIN_CONF_FILENAME=heleos_conf.ini
-    Q_DB_NAME="ovs_neutron"
     Q_PLUGIN_CLASS="neutron.plugins.embrane.plugins.embrane_ovs_plugin.EmbraneOvsPlugin"
 }
 
diff --git a/lib/neutron_plugins/ibm b/lib/neutron_plugins/ibm
index 3aef9d0..39b0040 100644
--- a/lib/neutron_plugins/ibm
+++ b/lib/neutron_plugins/ibm
@@ -60,7 +60,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/ibm
     Q_PLUGIN_CONF_FILENAME=sdnve_neutron_plugin.ini
-    Q_DB_NAME="sdnve_neutron"
     Q_PLUGIN_CLASS="neutron.plugins.ibm.sdnve_neutron_plugin.SdnvePluginV2"
 }
 
diff --git a/lib/neutron_plugins/linuxbridge b/lib/neutron_plugins/linuxbridge
index 113a7df..5f989ae 100644
--- a/lib/neutron_plugins/linuxbridge
+++ b/lib/neutron_plugins/linuxbridge
@@ -10,7 +10,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/linuxbridge
     Q_PLUGIN_CONF_FILENAME=linuxbridge_conf.ini
-    Q_DB_NAME="neutron_linux_bridge"
     Q_PLUGIN_CLASS="neutron.plugins.linuxbridge.lb_neutron_plugin.LinuxBridgePluginV2"
 }
 
diff --git a/lib/neutron_plugins/midonet b/lib/neutron_plugins/midonet
index c5373d6..6ccd502 100644
--- a/lib/neutron_plugins/midonet
+++ b/lib/neutron_plugins/midonet
@@ -26,7 +26,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/midonet
     Q_PLUGIN_CONF_FILENAME=midonet.ini
-    Q_DB_NAME="neutron_midonet"
     Q_PLUGIN_CLASS="neutron.plugins.midonet.plugin.MidonetPluginV2"
 }
 
diff --git a/lib/neutron_plugins/ml2 b/lib/neutron_plugins/ml2
index 9966373..f7f7838 100644
--- a/lib/neutron_plugins/ml2
+++ b/lib/neutron_plugins/ml2
@@ -50,7 +50,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/ml2
     Q_PLUGIN_CONF_FILENAME=ml2_conf.ini
-    Q_DB_NAME="neutron_ml2"
     Q_PLUGIN_CLASS="neutron.plugins.ml2.plugin.Ml2Plugin"
     # The ML2 plugin delegates L3 routing/NAT functionality to
     # the L3 service plugin which must therefore be specified.
@@ -99,7 +98,7 @@
     fi
 
     # Since we enable the tunnel TypeDrivers, also enable a local_ip
-    iniset /$Q_PLUGIN_CONF_FILE ovs local_ip $HOST_IP
+    iniset /$Q_PLUGIN_CONF_FILE ovs local_ip $TUNNEL_ENDPOINT_IP
 
     populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2 mechanism_drivers=$Q_ML2_PLUGIN_MECHANISM_DRIVERS
 
@@ -112,6 +111,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/neutron_plugins/nec b/lib/neutron_plugins/nec
index d76f7d4..f8d98c3 100644
--- a/lib/neutron_plugins/nec
+++ b/lib/neutron_plugins/nec
@@ -39,7 +39,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/nec
     Q_PLUGIN_CONF_FILENAME=nec.ini
-    Q_DB_NAME="neutron_nec"
     Q_PLUGIN_CLASS="neutron.plugins.nec.nec_plugin.NECPluginV2"
 }
 
diff --git a/lib/neutron_plugins/nuage b/lib/neutron_plugins/nuage
index 86f09d2..52d85a2 100644
--- a/lib/neutron_plugins/nuage
+++ b/lib/neutron_plugins/nuage
@@ -20,7 +20,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/nuage
     Q_PLUGIN_CONF_FILENAME=nuage_plugin.ini
-    Q_DB_NAME="nuage_neutron"
     Q_PLUGIN_CLASS="neutron.plugins.nuage.plugin.NuagePlugin"
     Q_PLUGIN_EXTENSIONS_PATH=neutron/plugins/nuage/extensions
     #Nuage specific Neutron defaults. Actual value must be set and sourced
diff --git a/lib/neutron_plugins/ofagent_agent b/lib/neutron_plugins/ofagent_agent
index b8321f3..66283ad 100644
--- a/lib/neutron_plugins/ofagent_agent
+++ b/lib/neutron_plugins/ofagent_agent
@@ -54,7 +54,7 @@
             die $LINENO "You are running OVS version $OVS_VERSION. OVS 1.4+ is required for tunneling between multiple hosts."
         fi
         iniset /$Q_PLUGIN_CONF_FILE ovs enable_tunneling True
-        iniset /$Q_PLUGIN_CONF_FILE ovs local_ip $HOST_IP
+        iniset /$Q_PLUGIN_CONF_FILE ovs local_ip $TUNNEL_ENDPOINT_IP
     fi
 
     # Setup physical network bridge mappings.  Override
diff --git a/lib/neutron_plugins/oneconvergence b/lib/neutron_plugins/oneconvergence
index 06f1eee..e5f0d71 100644
--- a/lib/neutron_plugins/oneconvergence
+++ b/lib/neutron_plugins/oneconvergence
@@ -19,7 +19,6 @@
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/oneconvergence
     Q_PLUGIN_CONF_FILENAME=nvsdplugin.ini
     Q_PLUGIN_CLASS="neutron.plugins.oneconvergence.plugin.OneConvergencePluginV2"
-    Q_DB_NAME='oc_nvsd_neutron'
 }
 
 # Configure plugin specific information
diff --git a/lib/neutron_plugins/openvswitch b/lib/neutron_plugins/openvswitch
index fc81092..c468132 100644
--- a/lib/neutron_plugins/openvswitch
+++ b/lib/neutron_plugins/openvswitch
@@ -10,7 +10,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/openvswitch
     Q_PLUGIN_CONF_FILENAME=ovs_neutron_plugin.ini
-    Q_DB_NAME="ovs_neutron"
     Q_PLUGIN_CLASS="neutron.plugins.openvswitch.ovs_neutron_plugin.OVSNeutronPluginV2"
 }
 
diff --git a/lib/neutron_plugins/openvswitch_agent b/lib/neutron_plugins/openvswitch_agent
index fbc013f..5adb0c5 100644
--- a/lib/neutron_plugins/openvswitch_agent
+++ b/lib/neutron_plugins/openvswitch_agent
@@ -48,7 +48,7 @@
             die $LINENO "You are running OVS version $OVS_VERSION. OVS 1.4+ is required for tunneling between multiple hosts."
         fi
         iniset /$Q_PLUGIN_CONF_FILE ovs enable_tunneling True
-        iniset /$Q_PLUGIN_CONF_FILE ovs local_ip $HOST_IP
+        iniset /$Q_PLUGIN_CONF_FILE ovs local_ip $TUNNEL_ENDPOINT_IP
     fi
 
     # Setup physical network bridge mappings.  Override
diff --git a/lib/neutron_plugins/ovs_base b/lib/neutron_plugins/ovs_base
index 26c5489..616a236 100644
--- a/lib/neutron_plugins/ovs_base
+++ b/lib/neutron_plugins/ovs_base
@@ -7,6 +7,7 @@
 
 OVS_BRIDGE=${OVS_BRIDGE:-br-int}
 PUBLIC_BRIDGE=${PUBLIC_BRIDGE:-br-ex}
+OVS_DATAPATH_TYPE=${OVS_DATAPATH_TYPE:-""}
 
 function is_neutron_ovs_base_plugin {
     # Yes, we use OVS.
@@ -17,6 +18,9 @@
     local bridge=$1
     neutron-ovs-cleanup
     sudo ovs-vsctl --no-wait -- --may-exist add-br $bridge
+    if [[ $OVS_DATAPATH_TYPE != "" ]]; then
+        sudo ovs-vsctl set Bridge $bridge datapath_type=${OVS_DATAPATH_TYPE}
+    fi
     sudo ovs-vsctl --no-wait br-set-external-id $bridge bridge-id $bridge
 }
 
diff --git a/lib/neutron_plugins/plumgrid b/lib/neutron_plugins/plumgrid
index 178bca7..37b9e4c 100644
--- a/lib/neutron_plugins/plumgrid
+++ b/lib/neutron_plugins/plumgrid
@@ -17,7 +17,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/plumgrid
     Q_PLUGIN_CONF_FILENAME=plumgrid.ini
-    Q_DB_NAME="plumgrid_neutron"
     Q_PLUGIN_CLASS="neutron.plugins.plumgrid.plumgrid_plugin.plumgrid_plugin.NeutronPluginPLUMgridV2"
     PLUMGRID_DIRECTOR_IP=${PLUMGRID_DIRECTOR_IP:-localhost}
     PLUMGRID_DIRECTOR_PORT=${PLUMGRID_DIRECTOR_PORT:-7766}
diff --git a/lib/neutron_plugins/ryu b/lib/neutron_plugins/ryu
index ceb89fa..f45a797 100644
--- a/lib/neutron_plugins/ryu
+++ b/lib/neutron_plugins/ryu
@@ -25,7 +25,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/ryu
     Q_PLUGIN_CONF_FILENAME=ryu.ini
-    Q_DB_NAME="ovs_neutron"
     Q_PLUGIN_CLASS="neutron.plugins.ryu.ryu_neutron_plugin.RyuNeutronPluginV2"
 }
 
diff --git a/lib/neutron_plugins/vmware_nsx b/lib/neutron_plugins/vmware_nsx
index c7672db..5802ebf 100644
--- a/lib/neutron_plugins/vmware_nsx
+++ b/lib/neutron_plugins/vmware_nsx
@@ -40,7 +40,6 @@
 function neutron_plugin_configure_common {
     Q_PLUGIN_CONF_PATH=etc/neutron/plugins/vmware
     Q_PLUGIN_CONF_FILENAME=nsx.ini
-    Q_DB_NAME="neutron_nsx"
     Q_PLUGIN_CLASS="neutron.plugins.vmware.plugin.NsxPlugin"
 }
 
diff --git a/lib/nova b/lib/nova
index ebdb6b4..8da8b69 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
@@ -480,18 +480,6 @@
         iniset $NOVA_CONF DEFAULT notification_driver "messaging"
     fi
 
-    # Provide some transition from ``EXTRA_FLAGS`` to ``EXTRA_OPTS``
-    if [[ -z "$EXTRA_OPTS" && -n "$EXTRA_FLAGS" ]]; then
-        EXTRA_OPTS=$EXTRA_FLAGS
-    fi
-
-    # Define extra nova conf flags by defining the array ``EXTRA_OPTS``.
-    # For Example: ``EXTRA_OPTS=(foo=true bar=2)``
-    for I in "${EXTRA_OPTS[@]}"; do
-        # Replace the first '=' with ' ' for iniset syntax
-        iniset $NOVA_CONF DEFAULT ${I/=/ }
-    done
-
     # All nova-compute workers need to know the vnc configuration options
     # These settings don't hurt anything if n-xvnc and n-novnc are disabled
     if is_service_enabled n-cpu; then
diff --git a/lib/nova_plugins/hypervisor-baremetal b/lib/nova_plugins/hypervisor-baremetal
index 1d4d414..22d16a6 100644
--- a/lib/nova_plugins/hypervisor-baremetal
+++ b/lib/nova_plugins/hypervisor-baremetal
@@ -58,12 +58,6 @@
         sudo cp "$FILES/dnsmasq-for-baremetal-from-nova-network.conf" "$BM_DNSMASQ_CONF"
         iniset $NOVA_CONF DEFAULT dnsmasq_config_file "$BM_DNSMASQ_CONF"
     fi
-
-    # Define extra baremetal nova conf flags by defining the array ``EXTRA_BAREMETAL_OPTS``.
-    for I in "${EXTRA_BAREMETAL_OPTS[@]}"; do
-        # Attempt to convert flags to options
-        iniset $NOVA_CONF baremetal ${I/=/ }
-    done
 }
 
 # install_nova_hypervisor() - Install external components
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 02906b7..e58e513 100644
--- a/lib/tls
+++ b/lib/tls
@@ -18,6 +18,9 @@
 # - configure_proxy
 # - start_tls_proxy
 
+# - stop_tls_proxy
+# - cleanup_CA
+
 # - make_root_CA
 # - make_int_CA
 # - make_cert ca-dir cert-name "common-name" ["alt-name" ...]
@@ -320,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
@@ -372,6 +376,22 @@
 }
 
 
+# Cleanup Functions
+# ===============
+
+
+# Stops all stud processes. This should be done only after all services
+# using tls configuration are down.
+function stop_tls_proxy {
+    killall stud
+}
+
+
+# Remove CA along with configuration, as well as the local server certificate
+function cleanup_CA {
+    rm -rf "$DATA_DIR/CA" "$DEVSTACK_CERT"
+}
+
 # Tell emacs to use shell-script-mode
 ## Local variables:
 ## mode: shell-script
diff --git a/lib/trove b/lib/trove
index 2552745..f6a933e 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
@@ -180,6 +180,7 @@
     iniset $TROVE_CONF_DIR/trove-guestagent.conf DEFAULT nova_proxy_admin_pass $RADMIN_USER_PASS
     iniset $TROVE_CONF_DIR/trove-guestagent.conf DEFAULT trove_auth_url $TROVE_AUTH_ENDPOINT
     iniset $TROVE_CONF_DIR/trove-guestagent.conf DEFAULT control_exchange trove
+    iniset $TROVE_CONF_DIR/trove-guestagent.conf DEFAULT ignore_users os_admin
     iniset $TROVE_CONF_DIR/trove-guestagent.conf DEFAULT log_dir /tmp/
     iniset $TROVE_CONF_DIR/trove-guestagent.conf DEFAULT log_file trove-guestagent.log
     setup_trove_logging $TROVE_CONF_DIR/trove-guestagent.conf
diff --git a/samples/local.conf b/samples/local.conf
index c8126c2..20c5892 100644
--- a/samples/local.conf
+++ b/samples/local.conf
@@ -24,8 +24,10 @@
 # While ``stack.sh`` is happy to run without ``localrc``, devlife is better when
 # there are a few minimal variables set:
 
-# If the ``*_PASSWORD`` variables are not set here you will be prompted to enter
-# values for them by ``stack.sh`` and they will be added to ``local.conf``.
+# If the ``SERVICE_TOKEN`` and ``*_PASSWORD`` variables are not set
+# here you will be prompted to enter values for them by ``stack.sh``
+# and they will be added to ``local.conf``.
+SERVICE_TOKEN=azertytoken
 ADMIN_PASSWORD=nomoresecrete
 MYSQL_PASSWORD=stackdb
 RABBIT_PASSWORD=stackqueue
diff --git a/stack.sh b/stack.sh
index 6d81691..f1cfe97 100755
--- a/stack.sh
+++ b/stack.sh
@@ -152,7 +152,7 @@
 # Look for obsolete stuff
 if [[ ,${ENABLED_SERVICES}, =~ ,"swift", ]]; then
     echo "FATAL: 'swift' is not supported as a service name"
-    echo "FATAL: Use the actual swift service names to enable tham as required:"
+    echo "FATAL: Use the actual swift service names to enable them as required:"
     echo "FATAL: s-proxy s-object s-container s-account"
     exit 1
 fi
@@ -219,15 +219,6 @@
 # Some distros need to add repos beyond the defaults provided by the vendor
 # to pick up required packages.
 
-# The Debian Wheezy official repositories do not contain all required packages,
-# add gplhost repository.
-if [[ "$os_VENDOR" =~ (Debian) ]]; then
-    echo 'deb http://archive.gplhost.com/debian grizzly main' | sudo tee /etc/apt/sources.list.d/gplhost_wheezy-backports.list
-    echo 'deb http://archive.gplhost.com/debian grizzly-backports main' | sudo tee -a /etc/apt/sources.list.d/gplhost_wheezy-backports.list
-    apt_get update
-    apt_get install --force-yes gplhost-archive-keyring
-fi
-
 if [[ is_fedora && $DISTRO =~ (rhel) ]]; then
     # Installing Open vSwitch on RHEL requires enabling the RDO repo.
     RHEL6_RDO_REPO_RPM=${RHEL6_RDO_REPO_RPM:-"http://rdo.fedorapeople.org/openstack-icehouse/rdo-release-icehouse.rpm"}
@@ -317,9 +308,6 @@
 # Allow the use of an alternate hostname (such as localhost/127.0.0.1) for service endpoints.
 SERVICE_HOST=${SERVICE_HOST:-$HOST_IP}
 
-# Allow the use of an alternate protocol (such as https) for service endpoints
-SERVICE_PROTOCOL=${SERVICE_PROTOCOL:-http}
-
 # Configure services to use syslog instead of writing to individual log files
 SYSLOG=`trueorfalse False $SYSLOG`
 SYSLOG_HOST=${SYSLOG_HOST:-$HOST_IP}
@@ -530,6 +518,12 @@
     echo $@ >&3
 }
 
+if [[ is_fedora && $DISTRO =~ (rhel) ]]; then
+    # poor old python2.6 doesn't have argparse by default, which
+    # outfilter.py uses
+    is_package_installed python-argparse || install_package python-argparse
+fi
+
 # Set up logging for ``stack.sh``
 # Set ``LOGFILE`` to turn on logging
 # Append '.xxxxxxxx' to the given name to maintain history
@@ -665,7 +659,7 @@
     $TOP_DIR/tools/install_pip.sh
 fi
 
-# Do the ugly hacks for borken packages and distros
+# Do the ugly hacks for broken packages and distros
 $TOP_DIR/tools/fixup_stuff.sh
 
 
@@ -796,7 +790,6 @@
     install_ceilometer
     echo_summary "Configuring Ceilometer"
     configure_ceilometer
-    configure_ceilometerclient
 fi
 
 if is_service_enabled heat; then
@@ -1399,41 +1392,6 @@
     echo_summary "WARNING: $DEPRECATED_TEXT"
 fi
 
-# TODO(dtroyer): Remove EXTRA_OPTS after stable/icehouse branch is cut
-# Specific warning for deprecated configs
-if [[ -n "$EXTRA_OPTS" ]]; then
-    echo ""
-    echo_summary "WARNING: EXTRA_OPTS is used"
-    echo "You are using EXTRA_OPTS to pass configuration into nova.conf."
-    echo "Please convert that configuration in localrc to a nova.conf section in local.conf:"
-    echo "EXTRA_OPTS will be removed early in the Juno development cycle"
-    echo "
-[[post-config|\$NOVA_CONF]]
-[DEFAULT]
-"
-    for I in "${EXTRA_OPTS[@]}"; do
-        # Replace the first '=' with ' ' for iniset syntax
-        echo ${I}
-    done
-fi
-
-# TODO(dtroyer): Remove EXTRA_BAREMETAL_OPTS after stable/icehouse branch is cut
-if [[ -n "$EXTRA_BAREMETAL_OPTS" ]]; then
-    echo ""
-    echo_summary "WARNING: EXTRA_BAREMETAL_OPTS is used"
-    echo "You are using EXTRA_BAREMETAL_OPTS to pass configuration into nova.conf."
-    echo "Please convert that configuration in localrc to a nova.conf section in local.conf:"
-    echo "EXTRA_BAREMETAL_OPTS will be removed early in the Juno development cycle"
-    echo "
-[[post-config|\$NOVA_CONF]]
-[baremetal]
-"
-    for I in "${EXTRA_BAREMETAL_OPTS[@]}"; do
-        # Replace the first '=' with ' ' for iniset syntax
-        echo ${I}
-    done
-fi
-
 # TODO(dtroyer): Remove Q_AGENT_EXTRA_AGENT_OPTS after stable/juno branch is cut
 if [[ -n "$Q_AGENT_EXTRA_AGENT_OPTS" ]]; then
     echo ""
@@ -1468,40 +1426,6 @@
     done
 fi
 
-# TODO(dtroyer): Remove Q_DHCP_EXTRA_DEFAULT_OPTS after stable/icehouse branch is cut
-if [[ -n "$Q_DHCP_EXTRA_DEFAULT_OPTS" ]]; then
-    echo ""
-    echo_summary "WARNING: Q_DHCP_EXTRA_DEFAULT_OPTS is used"
-    echo "You are using Q_DHCP_EXTRA_DEFAULT_OPTS to pass configuration into $Q_DHCP_CONF_FILE."
-    echo "Please convert that configuration in localrc to a $Q_DHCP_CONF_FILE section in local.conf:"
-    echo "Q_DHCP_EXTRA_DEFAULT_OPTS will be removed early in the Juno development cycle"
-    echo "
-[[post-config|/\$Q_DHCP_CONF_FILE]]
-[DEFAULT]
-"
-    for I in "${Q_DHCP_EXTRA_DEFAULT_OPTS[@]}"; do
-        # Replace the first '=' with ' ' for iniset syntax
-        echo ${I}
-    done
-fi
-
-# TODO(dtroyer): Remove Q_SRV_EXTRA_DEFAULT_OPTS after stable/icehouse branch is cut
-if [[ -n "$Q_SRV_EXTRA_DEFAULT_OPTS" ]]; then
-    echo ""
-    echo_summary "WARNING: Q_SRV_EXTRA_DEFAULT_OPTS is used"
-    echo "You are using Q_SRV_EXTRA_DEFAULT_OPTS to pass configuration into $NEUTRON_CONF."
-    echo "Please convert that configuration in localrc to a $NEUTRON_CONF section in local.conf:"
-    echo "Q_SRV_EXTRA_DEFAULT_OPTS will be removed early in the Juno development cycle"
-    echo "
-[[post-config|\$NEUTRON_CONF]]
-[DEFAULT]
-"
-    for I in "${Q_SRV_EXTRA_DEFAULT_OPTS[@]}"; do
-        # Replace the first '=' with ' ' for iniset syntax
-        echo ${I}
-    done
-fi
-
 # TODO(dtroyer): Remove CINDER_MULTI_LVM_BACKEND after stable/juno branch is cut
 if [[ "$CINDER_MULTI_LVM_BACKEND" = "True" ]]; then
     echo ""
diff --git a/stackrc b/stackrc
index 4d3e8fc..9701d2d 100644
--- a/stackrc
+++ b/stackrc
@@ -363,7 +363,8 @@
         IMAGE_URLS=${IMAGE_URLS:-"http://partnerweb.vmware.com/programs/vmdkimage/cirros-0.3.2-i386-disk.vmdk"};;
     xenserver)
         DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-0.3.0-x86_64-disk}
-        IMAGE_URLS=${IMAGE_URLS:-"https://github.com/downloads/citrix-openstack/warehouse/cirros-0.3.0-x86_64-disk.vhd.tgz"};;
+        IMAGE_URLS=${IMAGE_URLS:-"https://github.com/downloads/citrix-openstack/warehouse/cirros-0.3.0-x86_64-disk.vhd.tgz"}
+        IMAGE_URLS+=",http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-uec.tar.gz";;
     *) # Default to Cirros with kernel, ramdisk and disk image
         DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-x86_64-uec}
         IMAGE_URLS=${IMAGE_URLS:-"http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-uec.tar.gz"};;
@@ -430,6 +431,9 @@
 # Undo requirements changes by global requirements
 UNDO_REQUIREMENTS=${UNDO_REQUIREMENTS:-True}
 
+# Allow the use of an alternate protocol (such as https) for service endpoints
+SERVICE_PROTOCOL=${SERVICE_PROTOCOL:-http}
+
 # Local variables:
 # mode: shell-script
 # End:
diff --git a/tools/xen/install_os_domU.sh b/tools/xen/install_os_domU.sh
index 44e8dc1..12e861e 100755
--- a/tools/xen/install_os_domU.sh
+++ b/tools/xen/install_os_domU.sh
@@ -207,6 +207,8 @@
             -e "s,\(d-i mirror/http/hostname string\).*,\1 $UBUNTU_INST_HTTP_HOSTNAME,g" \
             -e "s,\(d-i mirror/http/directory string\).*,\1 $UBUNTU_INST_HTTP_DIRECTORY,g" \
             -e "s,\(d-i mirror/http/proxy string\).*,\1 $UBUNTU_INST_HTTP_PROXY,g" \
+            -e "s,\(d-i passwd/root-password password\).*,\1 $GUEST_PASSWORD,g" \
+            -e "s,\(d-i passwd/root-password-again password\).*,\1 $GUEST_PASSWORD,g" \
             -i "${HTTP_SERVER_LOCATION}/devstackubuntupreseed.cfg"
     fi
 
@@ -382,10 +384,16 @@
     while ! ssh_no_check -q stack@$OS_VM_MANAGEMENT_ADDRESS "service devstack status | grep -q running"; do
         sleep 10
     done
-    echo -n "devstack is running"
+    echo -n "devstack service is running, waiting for stack.sh to start logging..."
+
+    while ! ssh_no_check -q stack@$OS_VM_MANAGEMENT_ADDRESS "test -e /tmp/devstack/log/stack.log"; do
+        sleep 10
+    done
     set -x
 
-    # Watch devstack's output
+    # Watch devstack's output (which doesn't start until stack.sh is running,
+    # but wait for run.sh (which starts stack.sh) to exit as that is what
+    # hopefully writes the succeded cookie.
     pid=`ssh_no_check -q stack@$OS_VM_MANAGEMENT_ADDRESS pgrep run.sh`
     ssh_no_check -q stack@$OS_VM_MANAGEMENT_ADDRESS "tail --pid $pid -n +1 -f /tmp/devstack/log/stack.log"
 
diff --git a/unstack.sh b/unstack.sh
index a5e7b87..fe5fc77 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -122,9 +122,10 @@
     stop_horizon
 fi
 
-# Kill TLS proxies
+# Kill TLS proxies and cleanup certificates
 if is_service_enabled tls-proxy; then
-    killall stud
+    stop_tls_proxy
+    cleanup_CA
 fi
 
 SCSI_PERSIST_DIR=$CINDER_STATE_PATH/volumes/*