Merge "XenAPI: Move some boot-time functions to install-time"
diff --git a/README.md b/README.md
index 7eacebd..40060a7 100644
--- a/README.md
+++ b/README.md
@@ -215,21 +215,6 @@
     [[post-config|/$Q_PLUGIN_CONF_FILE]]
     [linuxbridge]   # or [ovs]
 
-* ``Q_AGENT_EXTRA_AGENT_OPTS``:
-
-    [[post-config|/$Q_PLUGIN_CONF_FILE]]
-    [agent]
-
-* ``Q_AGENT_EXTRA_SRV_OPTS``:
-
-    [[post-config|/$Q_PLUGIN_CONF_FILE]]
-    [linuxbridge]   # or [ovs]
-
-* ``Q_SRV_EXTRA_DEFAULT_OPTS``:
-
-    [[post-config|$NEUTRON_CONF]]
-    [DEFAULT]
-
 Example extra config in `local.conf`:
 
     [[post-config|/$Q_PLUGIN_CONF_FILE]]
diff --git a/clean.sh b/clean.sh
index edbd04a..50d414c 100755
--- a/clean.sh
+++ b/clean.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/bin/bash
 
 # **clean.sh**
 
@@ -83,7 +83,10 @@
 fi
 
 # Clean projects
-cleanup_cinder
+
+# BUG: cinder tgt doesn't exit cleanly if it's not running.
+cleanup_cinder || /bin/true
+
 cleanup_glance
 cleanup_keystone
 cleanup_nova
diff --git a/doc/source/guides/devstack-with-nested-kvm.rst b/doc/source/guides/devstack-with-nested-kvm.rst
index 2538c8d..58ec3d3 100644
--- a/doc/source/guides/devstack-with-nested-kvm.rst
+++ b/doc/source/guides/devstack-with-nested-kvm.rst
@@ -19,7 +19,7 @@
 Configure Nested KVM for Intel-based Machines
 ---------------------------------------------
 
-Procedure to enable nested KVM virtualization on AMD-based machines.
+Procedure to enable nested KVM virtualization on Intel-based machines.
 
 Check if the nested KVM Kernel parameter is enabled:
 
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 0790d1e..855a2d6 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -163,11 +163,9 @@
 * `lib/ldap <lib/ldap.html>`__
 * `lib/neutron <lib/neutron.html>`__
 * `lib/nova <lib/nova.html>`__
-* `lib/opendaylight <lib/opendaylight.html>`__
 * `lib/oslo <lib/oslo.html>`__
 * `lib/rpc\_backend <lib/rpc_backend.html>`__
 * `lib/sahara <lib/sahara.html>`__
-* `lib/stackforge <lib/stackforge.html>`__
 * `lib/swift <lib/swift.html>`__
 * `lib/tempest <lib/tempest.html>`__
 * `lib/tls <lib/tls.html>`__
@@ -184,7 +182,6 @@
 * `extras.d/70-trove.sh <extras.d/70-trove.sh.html>`__
 * `extras.d/70-tuskar.sh <extras.d/70-tuskar.sh.html>`__
 * `extras.d/70-zaqar.sh <extras.d/70-zaqar.sh.html>`__
-* `extras.d/80-opendaylight.sh <extras.d/80-opendaylight.sh.html>`__
 * `extras.d/80-tempest.sh <extras.d/80-tempest.sh.html>`__
 
 Configuration
diff --git a/extras.d/80-opendaylight.sh b/extras.d/80-opendaylight.sh
deleted file mode 100644
index b673777..0000000
--- a/extras.d/80-opendaylight.sh
+++ /dev/null
@@ -1,76 +0,0 @@
-# opendaylight.sh - DevStack extras script
-
-if is_service_enabled odl-server odl-compute; then
-    # Initial source
-    [[ "$1" == "source" ]] && source $TOP_DIR/lib/opendaylight
-fi
-
-if is_service_enabled odl-server; then
-    if [[ "$1" == "source" ]]; then
-        # no-op
-        :
-    elif [[ "$1" == "stack" && "$2" == "install" ]]; then
-        install_opendaylight
-        configure_opendaylight
-        init_opendaylight
-    elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
-        configure_ml2_odl
-        # This has to start before Neutron
-        start_opendaylight
-    elif [[ "$1" == "stack" && "$2" == "post-extra" ]]; then
-        # no-op
-        :
-    fi
-
-    if [[ "$1" == "unstack" ]]; then
-        stop_opendaylight
-        cleanup_opendaylight
-    fi
-
-    if [[ "$1" == "clean" ]]; then
-        # no-op
-        :
-    fi
-fi
-
-if is_service_enabled odl-compute; then
-    if [[ "$1" == "source" ]]; then
-        # no-op
-        :
-    elif [[ "$1" == "stack" && "$2" == "install" ]]; then
-        install_opendaylight-compute
-    elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
-        if is_service_enabled nova; then
-            create_nova_conf_neutron
-        fi
-    elif [[ "$1" == "stack" && "$2" == "extra" ]]; then
-        echo_summary "Initializing OpenDaylight"
-        ODL_LOCAL_IP=${ODL_LOCAL_IP:-$HOST_IP}
-        ODL_MGR_PORT=${ODL_MGR_PORT:-6640}
-        read ovstbl <<< $(sudo ovs-vsctl get Open_vSwitch . _uuid)
-        sudo ovs-vsctl set-manager tcp:$ODL_MGR_IP:$ODL_MGR_PORT
-        if [[ -n "$ODL_PROVIDER_MAPPINGS" ]] && [[ "$ENABLE_TENANT_VLANS" == "True" ]]; then
-            sudo ovs-vsctl set Open_vSwitch $ovstbl \
-                other_config:provider_mappings=$ODL_PROVIDER_MAPPINGS
-        fi
-        sudo ovs-vsctl set Open_vSwitch $ovstbl other_config:local_ip=$ODL_LOCAL_IP
-    elif [[ "$1" == "stack" && "$2" == "post-extra" ]]; then
-        # no-op
-        :
-    fi
-
-    if [[ "$1" == "unstack" ]]; then
-        sudo ovs-vsctl del-manager
-        BRIDGES=$(sudo ovs-vsctl list-br)
-        for bridge in $BRIDGES ; do
-            sudo ovs-vsctl del-controller $bridge
-        done
-
-        stop_opendaylight-compute
-    fi
-
-    if [[ "$1" == "clean" ]]; then
-        # no-op
-        :
-    fi
-fi
diff --git a/files/debs/general b/files/debs/general
index e824d23..4050191 100644
--- a/files/debs/general
+++ b/files/debs/general
@@ -27,3 +27,4 @@
 libffi-dev
 libssl-dev # for pyOpenSSL
 gettext  # used for compiling message catalogs
+openjdk-7-jre-headless  # NOPRIME
diff --git a/files/default_catalog.templates b/files/default_catalog.templates
index a18d38f..4aab416 100644
--- a/files/default_catalog.templates
+++ b/files/default_catalog.templates
@@ -30,9 +30,9 @@
 catalog.RegionOne.volumev2.name = Volume Service V2
 
 
-catalog.RegionOne.ec2.publicURL = http://%SERVICE_HOST%:8773/services/Cloud
-catalog.RegionOne.ec2.adminURL = http://%SERVICE_HOST%:8773/services/Admin
-catalog.RegionOne.ec2.internalURL = http://%SERVICE_HOST%:8773/services/Cloud
+catalog.RegionOne.ec2.publicURL = http://%SERVICE_HOST%:8773/
+catalog.RegionOne.ec2.adminURL = http://%SERVICE_HOST%:8773/
+catalog.RegionOne.ec2.internalURL = http://%SERVICE_HOST%:8773/
 catalog.RegionOne.ec2.name = EC2 Service
 
 
diff --git a/files/rpms/general b/files/rpms/general
index 13c8a87..6f22391 100644
--- a/files/rpms/general
+++ b/files/rpms/general
@@ -26,3 +26,4 @@
 libyaml-devel
 gettext  # used for compiling message catalogs
 net-tools
+java-1.7.0-openjdk-headless  # NOPRIME
diff --git a/files/rpms/qpid b/files/rpms/qpid
index 9e3f10a..c5e2699 100644
--- a/files/rpms/qpid
+++ b/files/rpms/qpid
@@ -1,4 +1,4 @@
 qpid-proton-c-devel # NOPRIME
 python-qpid-proton # NOPRIME
 cyrus-sasl-lib # NOPRIME
-
+cyrus-sasl-plain # NOPRIME
diff --git a/functions-common b/functions-common
index d3b3c0c..6beb670 100644
--- a/functions-common
+++ b/functions-common
@@ -913,9 +913,9 @@
     echo $role_id
 }
 
-# Gets or adds user role
-# Usage: get_or_add_user_role <role> <user> <project>
-function get_or_add_user_role {
+# Gets or adds user role to project
+# Usage: get_or_add_user_project_role <role> <user> <project>
+function get_or_add_user_project_role {
     # Gets user role id
     local user_role_id=$(openstack role list \
         --user $2 \
diff --git a/gate/updown.sh b/gate/updown.sh
new file mode 100755
index 0000000..d2d7351
--- /dev/null
+++ b/gate/updown.sh
@@ -0,0 +1,24 @@
+#!/bin/bash -xe
+#
+# An up / down test for gate functional testing
+#
+# Note: this is expected to start running as jenkins
+
+# Step 1: give back sudoers permissions to devstack
+TEMPFILE=`mktemp`
+echo "stack ALL=(root) NOPASSWD:ALL" >$TEMPFILE
+chmod 0440 $TEMPFILE
+sudo chown root:root $TEMPFILE
+sudo mv $TEMPFILE /etc/sudoers.d/51_stack_sh
+
+# TODO: do something to start a guest to create crud that should
+# disappear
+
+# Step 2: unstack
+echo "Running unstack.sh"
+sudo -H -u stack stdbuf -oL -eL bash -ex ./unstack.sh
+
+# Step 3: clean
+echo "Running clean.sh"
+sudo -H -u stack stdbuf -oL -eL bash -ex ./clean.sh
+
diff --git a/lib/ceilometer b/lib/ceilometer
index f03bab2..698e8b0 100644
--- a/lib/ceilometer
+++ b/lib/ceilometer
@@ -108,7 +108,7 @@
     # Ceilometer
     if [[ "$ENABLED_SERVICES" =~ "ceilometer-api" ]]; then
 
-        create_service_user "ceilometer" "admin"
+        create_service_user "ceilometer"
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
             local ceilometer_service=$(get_or_create_service "ceilometer" \
@@ -121,7 +121,7 @@
         fi
         if is_service_enabled swift; then
             # Ceilometer needs ResellerAdmin role to access swift account stats.
-            get_or_add_user_role "ResellerAdmin" "ceilometer" $SERVICE_TENANT_NAME
+            get_or_add_user_project_role "ResellerAdmin" "ceilometer" $SERVICE_TENANT_NAME
         fi
     fi
 }
diff --git a/lib/cinder b/lib/cinder
index 12ba51e..0d157dd 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -65,21 +65,14 @@
 fi
 
 
-# Maintain this here for backward-compatibility with the old configuration
-# DEPRECATED: Use CINDER_ENABLED_BACKENDS instead
-# Support for multi lvm backend configuration (default is no support)
-CINDER_MULTI_LVM_BACKEND=$(trueorfalse False CINDER_MULTI_LVM_BACKEND)
-
 # Default backends
 # The backend format is type:name where type is one of the supported backend
 # types (lvm, nfs, etc) and name is the identifier used in the Cinder
 # configuration and for the volume type name.  Multiple backends are
 # comma-separated.
-if [[ $CINDER_MULTI_LVM_BACKEND == "False" ]]; then
-    CINDER_ENABLED_BACKENDS=${CINDER_ENABLED_BACKENDS:-lvm:${DEFAULT_VOLUME_GROUP_NAME##*-}}
-else
-    CINDER_ENABLED_BACKENDS=${CINDER_ENABLED_BACKENDS:-lvm:${DEFAULT_VOLUME_GROUP_NAME##*-},lvm:cinder}
-fi
+# The old ``CINDER_MULTI_LVM_BACKEND=True`` setting had a default of:
+# CINDER_ENABLED_BACKENDS=${CINDER_ENABLED_BACKENDS:-lvm:lvmdriver-1,lvm:lvmdriver-2}
+CINDER_ENABLED_BACKENDS=${CINDER_ENABLED_BACKENDS:-lvm:lvmdriver-1}
 
 
 # Should cinder perform secure deletion of volumes?
@@ -333,7 +326,7 @@
     # Cinder
     if [[ "$ENABLED_SERVICES" =~ "c-api" ]]; then
 
-        create_service_user "cinder" "admin"
+        create_service_user "cinder"
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
 
diff --git a/lib/cinder_backends/lvm b/lib/cinder_backends/lvm
index 4b9d8dc..d83c31a 100644
--- a/lib/cinder_backends/lvm
+++ b/lib/cinder_backends/lvm
@@ -77,6 +77,7 @@
     local line
 
     for pv_info in $(sudo pvs --noheadings -o name,vg_name --separator ';'); do
+        echo_summary "Evaluate PV info for Cinder lvm.conf: $pv_info"
         IFS=';' read pv vg <<< $pv_info
         for line in ${conf_entries}; do
             IFS='=' read label group <<< $line
diff --git a/lib/databases/mysql b/lib/databases/mysql
index 72c0f82..c8ceec2 100644
--- a/lib/databases/mysql
+++ b/lib/databases/mysql
@@ -28,17 +28,14 @@
     stop_service $MYSQL
     if is_ubuntu; then
         # Get ruthless with mysql
-        stop_service $MYSQL
         apt_get purge -y mysql* mariadb*
         sudo rm -rf /var/lib/mysql
         sudo rm -rf /etc/mysql
         return
     elif is_fedora; then
-        stop_service mariadb
         uninstall_package mariadb-server
         sudo rm -rf /var/lib/mysql
     elif is_suse; then
-        stop_service mysql
         uninstall_package mysql-community-server
         sudo rm -rf /var/lib/mysql
     else
diff --git a/lib/dstat b/lib/dstat
index 8165e5c..740e48f 100644
--- a/lib/dstat
+++ b/lib/dstat
@@ -40,7 +40,10 @@
 
 # stop_dstat() stop dstat process
 function stop_dstat {
-    screen_stop dstat
+    # dstat runs as a console, not as a service, and isn't trackable
+    # via the normal mechanisms for devstack. So lets just do a
+    # killall and move on.
+    killall dstat || /bin/true
 }
 
 # Restore xtrace
diff --git a/lib/glance b/lib/glance
old mode 100644
new mode 100755
index 0340c21..eb1df2e
--- a/lib/glance
+++ b/lib/glance
@@ -70,7 +70,6 @@
 # Tell Tempest this project is present
 TEMPEST_SERVICES+=,glance
 
-
 # Functions
 # ---------
 
@@ -184,6 +183,12 @@
         iniset $GLANCE_API_CONF DEFAULT registry_client_protocol https
     fi
 
+    # Format logging
+    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
+        setup_colorized_logging $GLANCE_API_CONF DEFAULT "project_id" "user_id"
+        setup_colorized_logging $GLANCE_REGISTRY_CONF DEFAULT "project_id" "user_id"
+    fi
+
     cp -p $GLANCE_DIR/etc/glance-registry-paste.ini $GLANCE_REGISTRY_PASTE_INI
 
     cp -p $GLANCE_DIR/etc/glance-api-paste.ini $GLANCE_API_PASTE_INI
@@ -239,7 +244,7 @@
 
             local glance_swift_user=$(get_or_create_user "glance-swift" \
                 "$SERVICE_PASSWORD" "glance-swift@example.com")
-            get_or_add_user_role "ResellerAdmin" $glance_swift_user $SERVICE_TENANT_NAME
+            get_or_add_user_project_role "ResellerAdmin" $glance_swift_user $SERVICE_TENANT_NAME
         fi
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
@@ -308,6 +313,10 @@
 
     git_clone $GLANCE_REPO $GLANCE_DIR $GLANCE_BRANCH
     setup_develop $GLANCE_DIR
+    if is_service_enabled g-graffiti; then
+        ${TOP_DIR}/pkg/elasticsearch.sh download
+        ${TOP_DIR}/pkg/elasticsearch.sh install
+    fi
 }
 
 # start_glance() - Start running processes, including screen
@@ -321,6 +330,9 @@
     run_process g-reg "$GLANCE_BIN_DIR/glance-registry --config-file=$GLANCE_CONF_DIR/glance-registry.conf"
     run_process g-api "$GLANCE_BIN_DIR/glance-api --config-file=$GLANCE_CONF_DIR/glance-api.conf"
 
+    if is_service_enabled g-graffiti; then
+        ${TOP_DIR}/pkg/elasticsearch.sh start
+    fi
     echo "Waiting for g-api ($GLANCE_HOSTPORT) to start..."
     if ! wait_for_service $SERVICE_TIMEOUT $GLANCE_SERVICE_PROTOCOL://$GLANCE_HOSTPORT; then
         die $LINENO "g-api did not start"
@@ -334,7 +346,6 @@
     stop_process g-reg
 }
 
-
 # Restore xtrace
 $XTRACE
 
diff --git a/lib/ironic b/lib/ironic
index 921bcf1..7ffa6a5 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -362,6 +362,7 @@
     if [[ "$ENABLED_SERVICES" =~ "ir-api" ]]; then
         # Get ironic user if exists
 
+        # NOTE(Shrews): This user MUST have admin level privileges!
         create_service_user "ironic" "admin"
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
diff --git a/lib/keystone b/lib/keystone
index 79806b8..2da2d1b 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -365,7 +365,7 @@
     local admin_tenant=$(get_or_create_project "admin")
     local admin_user=$(get_or_create_user "admin" "$ADMIN_PASSWORD")
     local admin_role=$(get_or_create_role "admin")
-    get_or_add_user_role $admin_role $admin_user $admin_tenant
+    get_or_add_user_project_role $admin_role $admin_user $admin_tenant
 
     # Create service project/role
     get_or_create_project "$SERVICE_TENANT_NAME"
@@ -394,10 +394,10 @@
     local demo_user=$(get_or_create_user "demo" \
         "$ADMIN_PASSWORD" "demo@example.com")
 
-    get_or_add_user_role $member_role $demo_user $demo_tenant
-    get_or_add_user_role $admin_role $admin_user $demo_tenant
-    get_or_add_user_role $another_role $demo_user $demo_tenant
-    get_or_add_user_role $member_role $demo_user $invis_tenant
+    get_or_add_user_project_role $member_role $demo_user $demo_tenant
+    get_or_add_user_project_role $admin_role $admin_user $demo_tenant
+    get_or_add_user_project_role $another_role $demo_user $demo_tenant
+    get_or_add_user_project_role $member_role $demo_user $invis_tenant
 
     get_or_create_group "developers" "default" "openstack developers"
     get_or_create_group "testers" "default"
@@ -426,7 +426,7 @@
     local role=${2:-service}
 
     local user=$(get_or_create_user "$1" "$SERVICE_PASSWORD")
-    get_or_add_user_role "$role" "$user" "$SERVICE_TENANT_NAME"
+    get_or_add_user_project_role "$role" "$user" "$SERVICE_TENANT_NAME"
 }
 
 # Configure the service to use the auth token middleware.
diff --git a/lib/neutron_plugins/linuxbridge_agent b/lib/neutron_plugins/linuxbridge_agent
index ec17c01..c9ea1ca 100644
--- a/lib/neutron_plugins/linuxbridge_agent
+++ b/lib/neutron_plugins/linuxbridge_agent
@@ -50,20 +50,6 @@
     fi
     AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-linuxbridge-agent"
     iniset /$Q_PLUGIN_CONF_FILE agent tunnel_types $Q_TUNNEL_TYPES
-    # Define extra "AGENT" configuration options when q-agt is configured by defining
-    # the array ``Q_AGENT_EXTRA_AGENT_OPTS``.
-    # For Example: ``Q_AGENT_EXTRA_AGENT_OPTS=(foo=true bar=2)``
-    for I in "${Q_AGENT_EXTRA_AGENT_OPTS[@]}"; do
-        # Replace the first '=' with ' ' for iniset syntax
-        iniset /$Q_PLUGIN_CONF_FILE agent ${I/=/ }
-    done
-    # Define extra "LINUX_BRIDGE" configuration options when q-agt is configured by defining
-    # the array ``Q_AGENT_EXTRA_SRV_OPTS``.
-    # For Example: ``Q_AGENT_EXTRA_SRV_OPTS=(foo=true bar=2)``
-    for I in "${Q_AGENT_EXTRA_SRV_OPTS[@]}"; do
-        # Replace the first '=' with ' ' for iniset syntax
-        iniset /$Q_PLUGIN_CONF_FILE linux_bridge ${I/=/ }
-    done
 }
 
 function neutron_plugin_setup_interface_driver {
diff --git a/lib/neutron_plugins/ofagent_agent b/lib/neutron_plugins/ofagent_agent
index 915badc..d38fbeb 100644
--- a/lib/neutron_plugins/ofagent_agent
+++ b/lib/neutron_plugins/ofagent_agent
@@ -84,13 +84,6 @@
     AGENT_BINARY="$NEUTRON_BIN_DIR/neutron-ofagent-agent"
 
     iniset /$Q_PLUGIN_CONF_FILE agent tunnel_types $Q_TUNNEL_TYPES
-    # Define extra "AGENT" configuration options when q-agt is configured by defining
-    # defining the array ``Q_AGENT_EXTRA_AGENT_OPTS``.
-    # For Example: ``Q_AGENT_EXTRA_AGENT_OPTS=(foo=true bar=2)``
-    for I in "${Q_AGENT_EXTRA_AGENT_OPTS[@]}"; do
-        # Replace the first '=' with ' ' for iniset syntax
-        iniset /$Q_PLUGIN_CONF_FILE agent ${I/=/ }
-    done
 }
 
 function neutron_plugin_setup_interface_driver {
diff --git a/lib/neutron_plugins/openvswitch_agent b/lib/neutron_plugins/openvswitch_agent
index 2ab61b0..1d24f3b 100644
--- a/lib/neutron_plugins/openvswitch_agent
+++ b/lib/neutron_plugins/openvswitch_agent
@@ -104,20 +104,6 @@
         iniset "/$Q_PLUGIN_CONF_FILE.domU" agent root_helper "$Q_RR_COMMAND"
     fi
     iniset /$Q_PLUGIN_CONF_FILE agent tunnel_types $Q_TUNNEL_TYPES
-    # Define extra "AGENT" configuration options when q-agt is configured by defining
-    # defining the array ``Q_AGENT_EXTRA_AGENT_OPTS``.
-    # For Example: ``Q_AGENT_EXTRA_AGENT_OPTS=(foo=true bar=2)``
-    for I in "${Q_AGENT_EXTRA_AGENT_OPTS[@]}"; do
-        # Replace the first '=' with ' ' for iniset syntax
-        iniset /$Q_PLUGIN_CONF_FILE agent ${I/=/ }
-    done
-    # Define extra "OVS" configuration options when q-agt is configured by defining
-    # defining the array ``Q_AGENT_EXTRA_SRV_OPTS``.
-    # For Example: ``Q_AGENT_EXTRA_SRV_OPTS=(foo=true bar=2)``
-    for I in "${Q_AGENT_EXTRA_SRV_OPTS[@]}"; do
-        # Replace the first '=' with ' ' for iniset syntax
-        iniset /$Q_PLUGIN_CONF_FILE ovs ${I/=/ }
-    done
 }
 
 function neutron_plugin_setup_interface_driver {
diff --git a/lib/nova b/lib/nova
index c760066..74a3411 100644
--- a/lib/nova
+++ b/lib/nova
@@ -356,6 +356,8 @@
     # Nova
     if [[ "$ENABLED_SERVICES" =~ "n-api" ]]; then
 
+        # NOTE(jamielennox): Nova doesn't need the admin role here, however neutron uses
+        # this service user when notifying nova of changes and that requires the admin role.
         create_service_user "nova" "admin"
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
@@ -383,7 +385,7 @@
         if is_service_enabled swift; then
             # Nova needs ResellerAdmin role to download images when accessing
             # swift through the s3 api.
-            get_or_add_user_role ResellerAdmin nova $SERVICE_TENANT_NAME
+            get_or_add_user_project_role ResellerAdmin nova $SERVICE_TENANT_NAME
         fi
 
         # EC2
@@ -393,9 +395,9 @@
                 "ec2" "EC2 Compatibility Layer")
             get_or_create_endpoint $ec2_service \
                 "$REGION_NAME" \
-                "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/services/Cloud" \
-                "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/services/Admin" \
-                "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/services/Cloud"
+                "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/" \
+                "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/" \
+                "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/"
         fi
     fi
 
diff --git a/lib/opendaylight b/lib/opendaylight
deleted file mode 100644
index 6518673..0000000
--- a/lib/opendaylight
+++ /dev/null
@@ -1,215 +0,0 @@
-#!/bin/bash
-#
-# lib/opendaylight
-# Functions to control the configuration and operation of the opendaylight service
-
-# Dependencies:
-#
-# ``functions`` file
-# ``DEST`` must be defined
-# ``STACK_USER`` must be defined
-
-# ``stack.sh`` calls the entry points in this order:
-#
-# - is_opendaylight_enabled
-# - is_opendaylight-compute_enabled
-# - install_opendaylight
-# - install_opendaylight-compute
-# - configure_opendaylight
-# - init_opendaylight
-# - start_opendaylight
-# - stop_opendaylight-compute
-# - stop_opendaylight
-# - cleanup_opendaylight
-
-# Save trace setting
-XTRACE=$(set +o | grep xtrace)
-set +o xtrace
-
-
-# For OVS_BRIDGE and PUBLIC_BRIDGE
-source $TOP_DIR/lib/neutron_plugins/ovs_base
-
-# Defaults
-# --------
-
-# The IP address of ODL. Set this in local.conf.
-# ODL_MGR_IP=
-ODL_MGR_IP=${ODL_MGR_IP:-$SERVICE_HOST}
-
-# The ODL endpoint URL
-ODL_ENDPOINT=${ODL_ENDPOINT:-http://${ODL_MGR_IP}:8080/controller/nb/v2/neutron}
-
-# The ODL username
-ODL_USERNAME=${ODL_USERNAME:-admin}
-
-# The ODL password
-ODL_PASSWORD=${ODL_PASSWORD:-admin}
-
-# Short name of ODL package
-ODL_NAME=${ODL_NAME:-distribution-karaf-0.2.1-Helium-SR1.1}
-
-# <define global variables here that belong to this project>
-ODL_DIR=$DEST/opendaylight
-
-# The OpenDaylight Package, currently using 'Hydrogen' release
-ODL_PKG=${ODL_PKG:-distribution-karaf-0.2.1-Helium-SR1.1.zip}
-
-# The OpenDaylight URL
-ODL_URL=${ODL_URL:-https://nexus.opendaylight.org/content/repositories/public/org/opendaylight/integration/distribution-karaf/0.2.1-Helium-SR1.1/}
-
-# Default arguments for OpenDaylight. This is typically used to set
-# Java memory options.
-# ``ODL_ARGS=Xmx1024m -XX:MaxPermSize=512m``
-ODL_ARGS=${ODL_ARGS:-"-XX:MaxPermSize=384m"}
-
-# How long to pause after ODL starts to let it complete booting
-ODL_BOOT_WAIT=${ODL_BOOT_WAIT:-20}
-
-# The physical provider network to device mapping
-ODL_PROVIDER_MAPPINGS=${ODL_PROVIDER_MAPPINGS:-physnet1:eth1}
-
-# Enable OpenDaylight l3 forwarding
-ODL_L3=${ODL_L3:-False}
-
-# Enable debug logs for odl ovsdb
-ODL_NETVIRT_DEBUG_LOGS=${ODL_NETVIRT_DEBUG_LOGS:-False}
-
-# The logging config file in ODL
-ODL_LOGGING_CONFIG=${ODL_LOGGING_CONFIG:-${ODL_DIR}/${ODL_NAME}/etc/org.ops4j.pax.logging.cfg}
-
-# Entry Points
-# ------------
-
-# Test if OpenDaylight is enabled
-# is_opendaylight_enabled
-function is_opendaylight_enabled {
-    [[ ,${ENABLED_SERVICES} =~ ,"odl-" ]] && return 0
-    return 1
-}
-
-# cleanup_opendaylight() - Remove residual data files, anything left over from previous
-# runs that a clean run would need to clean up
-function cleanup_opendaylight {
-    :
-}
-
-# configure_opendaylight() - Set config files, create data dirs, etc
-function configure_opendaylight {
-    # Add odl-ovsdb-openstack if it's not already there
-    local ODLOVSDB=$(cat $ODL_DIR/$ODL_NAME/etc/org.apache.karaf.features.cfg | grep featuresBoot= | grep odl)
-    if [ "$ODLOVSDB" == "" ]; then
-        sed -i '/^featuresBoot=/ s/$/,odl-ovsdb-openstack/' $ODL_DIR/$ODL_NAME/etc/org.apache.karaf.features.cfg
-    fi
-
-    # Configure OpenFlow 1.3 if it's not there
-    local OFLOW13=$(cat $ODL_DIR/$ODL_NAME/etc/custom.properties | grep ^of.version)
-    if [ "$OFLOW13" == "" ]; then
-        echo "ovsdb.of.version=1.3" >> $ODL_DIR/$ODL_NAME/etc/custom.properties
-    fi
-
-    # Configure L3 if the user wants it
-    if [ "${ODL_L3}" == "True" ]; then
-        # Configure L3 FWD if it's not there
-        local L3FWD=$(cat $ODL_DIR/$ODL_NAME/etc/custom.properties | grep ^ovsdb.l3.fwd.enabled)
-        if [ "$L3FWD" == "" ]; then
-            echo "ovsdb.l3.fwd.enabled=yes" >> $ODL_DIR/$ODL_NAME/etc/custom.properties
-        fi
-    fi
-
-    # Configure DEBUG logs for network virtualization in odl, if the user wants it
-    if [ "${ODL_NETVIRT_DEBUG_LOGS}" == "True" ]; then
-        local OVSDB_DEBUG_LOGS=$(cat $ODL_LOGGING_CONFIG | grep ^log4j.logger.org.opendaylight.ovsdb)
-        if [ "${OVSDB_DEBUG_LOGS}" == "" ]; then
-            echo 'log4j.logger.org.opendaylight.ovsdb = TRACE' >> $ODL_LOGGING_CONFIG
-            echo 'log4j.logger.org.opendaylight.ovsdb.lib = INFO' >> $ODL_LOGGING_CONFIG
-            echo 'log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.impl.NeutronL3Adapter = DEBUG' >> $ODL_LOGGING_CONFIG
-            echo 'log4j.logger.org.opendaylight.ovsdb.openstack.netvirt.impl.TenantNetworkManagerImpl = DEBUG' >> $ODL_LOGGING_CONFIG
-            echo 'log4j.logger.org.opendaylight.ovsdb.plugin.md.OvsdbInventoryManager = INFO' >> $ODL_LOGGING_CONFIG
-        fi
-        local ODL_NEUTRON_DEBUG_LOGS=$(cat $ODL_LOGGING_CONFIG | grep ^log4j.logger.org.opendaylight.controller.networkconfig.neutron)
-        if [ "${ODL_NEUTRON_DEBUG_LOGS}" == "" ]; then
-            echo 'log4j.logger.org.opendaylight.controller.networkconfig.neutron = TRACE' >> $ODL_LOGGING_CONFIG
-        fi
-    fi
-}
-
-function configure_ml2_odl {
-    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_odl url=$ODL_ENDPOINT
-    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_odl username=$ODL_USERNAME
-    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_odl password=$ODL_PASSWORD
-}
-
-# init_opendaylight() - Initialize databases, etc.
-function init_opendaylight {
-    # clean up from previous (possibly aborted) runs
-    # create required data files
-    :
-}
-
-# install_opendaylight() - Collect source and prepare
-function install_opendaylight {
-    local _pwd=$(pwd)
-
-    if is_ubuntu; then
-        install_package maven openjdk-7-jre openjdk-7-jdk
-    else
-        yum_install maven java-1.7.0-openjdk
-    fi
-
-    # Download OpenDaylight
-    mkdir -p $ODL_DIR
-    cd $ODL_DIR
-    wget -N $ODL_URL/$ODL_PKG
-    unzip -u $ODL_PKG
-}
-
-# install_opendaylight-compute - Make sure OVS is installed
-function install_opendaylight-compute {
-    # packages are the same as for Neutron OVS agent
-    _neutron_ovs_base_install_agent_packages
-}
-
-# start_opendaylight() - Start running processes, including screen
-function start_opendaylight {
-    if is_ubuntu; then
-        JHOME=/usr/lib/jvm/java-1.7.0-openjdk-amd64
-    else
-        JHOME=/usr/lib/jvm/java-1.7.0-openjdk
-    fi
-
-    # The flags to ODL have the following meaning:
-    #   -of13: runs ODL using OpenFlow 1.3 protocol support.
-    #   -virt ovsdb: Runs ODL in "virtualization" mode with OVSDB support
-
-    run_process odl-server "cd $ODL_DIR/$ODL_NAME && JAVA_HOME=$JHOME bin/karaf"
-
-    # Sleep a bit to let OpenDaylight finish starting up
-    sleep $ODL_BOOT_WAIT
-}
-
-# stop_opendaylight() - Stop running processes (non-screen)
-function stop_opendaylight {
-    stop_process odl-server
-}
-
-# stop_opendaylight-compute() - Remove OVS bridges
-function stop_opendaylight-compute {
-    # remove all OVS ports that look like Neutron created ports
-    for port in $(sudo ovs-vsctl list port | grep -o -e tap[0-9a-f\-]* -e q[rg]-[0-9a-f\-]*); do
-        sudo ovs-vsctl del-port ${port}
-    done
-
-    # remove all OVS bridges created by Neutron
-    for bridge in $(sudo ovs-vsctl list-br | grep -o -e ${OVS_BRIDGE} -e ${PUBLIC_BRIDGE}); do
-        sudo ovs-vsctl del-br ${bridge}
-    done
-}
-
-# Restore xtrace
-$XTRACE
-
-# Tell emacs to use shell-script-mode
-## Local variables:
-## mode: shell-script
-## End:
diff --git a/lib/rpc_backend b/lib/rpc_backend
index 981b80b..899748c 100644
--- a/lib/rpc_backend
+++ b/lib/rpc_backend
@@ -74,7 +74,8 @@
     if is_service_enabled rabbit; then
         # Obliterate rabbitmq-server
         uninstall_package rabbitmq-server
-        sudo killall epmd || sudo killall -9 epmd
+        # in case it's not actually running, /bin/true at the end
+        sudo killall epmd || sudo killall -9 epmd || /bin/true
         if is_ubuntu; then
             # And the Erlang runtime too
             apt_get purge -y erlang*
@@ -342,6 +343,7 @@
             install_package sasl2-bin
         elif is_fedora; then
             install_package cyrus-sasl-lib
+            install_package cyrus-sasl-plain
         fi
         local sasl_conf_file=/etc/sasl2/qpidd.conf
         sudo sed -i.bak '/PLAIN/!s/mech_list: /mech_list: PLAIN /' $sasl_conf_file
diff --git a/lib/sahara b/lib/sahara
index cb6ecc3..da4fbcd 100644
--- a/lib/sahara
+++ b/lib/sahara
@@ -61,7 +61,7 @@
 # service     sahara    admin
 function create_sahara_accounts {
 
-    create_service_user "sahara" "admin"
+    create_service_user "sahara"
 
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
 
@@ -124,6 +124,10 @@
     if is_service_enabled neutron; then
         iniset $SAHARA_CONF_FILE DEFAULT use_neutron true
         iniset $SAHARA_CONF_FILE DEFAULT use_floating_ips true
+
+        if is_ssl_enabled_service "neutron" || is_service_enabled tls-proxy; then
+            iniset $SAHARA_CONF_FILE neutron ca_file $SSL_BUNDLE_FILE
+        fi
     else
         iniset $SAHARA_CONF_FILE DEFAULT use_neutron false
         iniset $SAHARA_CONF_FILE DEFAULT use_floating_ips false
@@ -131,10 +135,30 @@
 
     if is_service_enabled heat; then
         iniset $SAHARA_CONF_FILE DEFAULT infrastructure_engine heat
+
+        if is_ssl_enabled_service "heat" || is_service_enabled tls-proxy; then
+            iniset $SAHARA_CONF_FILE heat ca_file $SSL_BUNDLE_FILE
+        fi
     else
         iniset $SAHARA_CONF_FILE DEFAULT infrastructure_engine direct
     fi
 
+    if is_ssl_enabled_service "cinder" || is_service_enabled tls-proxy; then
+        iniset $SAHARA_CONF_FILE cinder ca_file $SSL_BUNDLE_FILE
+    fi
+
+    if is_ssl_enabled_service "nova" || is_service_enabled tls-proxy; then
+        iniset $SAHARA_CONF_FILE nova ca_file $SSL_BUNDLE_FILE
+    fi
+
+    if is_ssl_enabled_service "swift" || is_service_enabled tls-proxy; then
+        iniset $SAHARA_CONF_FILE swift ca_file $SSL_BUNDLE_FILE
+    fi
+
+    if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
+        iniset $SAHARA_CONF_FILE keystone ca_file $SSL_BUNDLE_FILE
+    fi
+
     iniset $SAHARA_CONF_FILE DEFAULT use_syslog $SYSLOG
 
     # Format logging
@@ -179,7 +203,7 @@
 # stop_sahara() - Stop running processes
 function stop_sahara {
     # Kill the Sahara screen windows
-    screen -S $SCREEN_NAME -p sahara -X kill
+    stop_process sahara
 }
 
 
diff --git a/lib/stackforge b/lib/stackforge
deleted file mode 100644
index cc3a689..0000000
--- a/lib/stackforge
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-#
-# lib/stackforge
-#
-# Functions to install stackforge libraries that we depend on so
-# that we can try their git versions during devstack gate.
-#
-# This is appropriate for python libraries that release to pypi and are
-# expected to be used beyond OpenStack like, but are requirements
-# for core services in global-requirements.
-#
-#     * wsme
-#     * pecan
-#
-# This is not appropriate for stackforge projects which are early stage
-# OpenStack tools
-
-# Dependencies:
-# ``functions`` file
-
-# ``stack.sh`` calls the entry points in this order:
-#
-# install_stackforge
-
-# Save trace setting
-XTRACE=$(set +o | grep xtrace)
-set +o xtrace
-
-
-# Defaults
-# --------
-WSME_DIR=$DEST/wsme
-PECAN_DIR=$DEST/pecan
-SQLALCHEMY_MIGRATE_DIR=$DEST/sqlalchemy-migrate
-
-# Entry Points
-# ------------
-
-# install_stackforge() - Collect source and prepare
-function install_stackforge {
-    git_clone $WSME_REPO $WSME_DIR $WSME_BRANCH
-    setup_package $WSME_DIR
-
-    git_clone $PECAN_REPO $PECAN_DIR $PECAN_BRANCH
-    setup_package $PECAN_DIR
-
-    git_clone $SQLALCHEMY_MIGRATE_REPO $SQLALCHEMY_MIGRATE_DIR $SQLALCHEMY_MIGRATE_BRANCH
-    setup_package $SQLALCHEMY_MIGRATE_DIR
-}
-
-# Restore xtrace
-$XTRACE
-
-# Local variables:
-# mode: shell-script
-# End:
diff --git a/lib/swift b/lib/swift
index d9f750c..56baa12 100644
--- a/lib/swift
+++ b/lib/swift
@@ -603,6 +603,8 @@
 
     local another_role=$(openstack role list | awk "/ anotherrole / { print \$2 }")
 
+    # NOTE(jroll): Swift doesn't need the admin role here, however Ironic uses
+    # temp urls, which break when uploaded by a non-admin role
     create_service_user "swift" "admin"
 
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
@@ -620,18 +622,18 @@
     die_if_not_set $LINENO swift_tenant_test1 "Failure creating swift_tenant_test1"
     SWIFT_USER_TEST1=$(get_or_create_user swiftusertest1 $swiftusertest1_password "test@example.com")
     die_if_not_set $LINENO SWIFT_USER_TEST1 "Failure creating SWIFT_USER_TEST1"
-    get_or_add_user_role admin $SWIFT_USER_TEST1 $swift_tenant_test1
+    get_or_add_user_project_role admin $SWIFT_USER_TEST1 $swift_tenant_test1
 
     local swift_user_test3=$(get_or_create_user swiftusertest3 $swiftusertest3_password "test3@example.com")
     die_if_not_set $LINENO swift_user_test3 "Failure creating swift_user_test3"
-    get_or_add_user_role $another_role $swift_user_test3 $swift_tenant_test1
+    get_or_add_user_project_role $another_role $swift_user_test3 $swift_tenant_test1
 
     local swift_tenant_test2=$(get_or_create_project swifttenanttest2)
     die_if_not_set $LINENO swift_tenant_test2 "Failure creating swift_tenant_test2"
 
     local swift_user_test2=$(get_or_create_user swiftusertest2 $swiftusertest2_password "test2@example.com")
     die_if_not_set $LINENO swift_user_test2 "Failure creating swift_user_test2"
-    get_or_add_user_role admin $swift_user_test2 $swift_tenant_test2
+    get_or_add_user_project_role admin $swift_user_test2 $swift_tenant_test2
 
     local swift_domain=$(get_or_create_domain swift_test 'Used for swift functional testing')
     die_if_not_set $LINENO swift_domain "Failure creating swift_test domain"
@@ -641,7 +643,7 @@
 
     local swift_user_test4=$(get_or_create_user swiftusertest4 $swiftusertest4_password "test4@example.com" $swift_domain)
     die_if_not_set $LINENO swift_user_test4 "Failure creating swift_user_test4"
-    get_or_add_user_role admin $swift_user_test4 $swift_tenant_test4
+    get_or_add_user_project_role admin $swift_user_test4 $swift_tenant_test4
 }
 
 # init_swift() - Initialize rings
diff --git a/lib/tempest b/lib/tempest
index 777d03e..8396a78 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -29,7 +29,6 @@
 # - ``USE_BLOCK_MIGRATION_FOR_LIVE_MIGRATION``
 # - ``DEFAULT_INSTANCE_TYPE``
 # - ``DEFAULT_INSTANCE_USER``
-# - ``CINDER_MULTI_LVM_BACKEND``
 # - ``CINDER_ENABLED_BACKENDS``
 #
 # ``stack.sh`` calls the entry points in this order:
@@ -65,7 +64,7 @@
 
 
 BOTO_MATERIALS_PATH="$FILES/images/s3-materials/cirros-${CIRROS_VERSION}"
-BOTO_CONF=$TEMPEST_DIR/boto.cfg
+BOTO_CONF=/etc/boto.cfg
 
 # Cinder/Volume variables
 TEMPEST_VOLUME_DRIVER=${TEMPEST_VOLUME_DRIVER:-default}
@@ -292,6 +291,9 @@
     iniset $TEMPEST_CONFIG identity admin_tenant_id $ADMIN_TENANT_ID
     iniset $TEMPEST_CONFIG identity admin_domain_name $ADMIN_DOMAIN_NAME
     iniset $TEMPEST_CONFIG identity auth_version ${TEMPEST_AUTH_VERSION:-v2}
+    if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
+        iniset $TEMPEST_CONFIG identity ca_certificates_file $SSL_BUNDLE_FILE
+    fi
 
     # Image
     # for the gate we want to be able to override this variable so we aren't
@@ -361,7 +363,7 @@
     iniset $TEMPEST_CONFIG network-feature-enabled api_extensions $network_api_extensions
 
     # boto
-    iniset $TEMPEST_CONFIG boto ec2_url "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/services/Cloud"
+    iniset $TEMPEST_CONFIG boto ec2_url "$EC2_SERVICE_PROTOCOL://$SERVICE_HOST:8773/"
     iniset $TEMPEST_CONFIG boto s3_url "http://$SERVICE_HOST:${S3_SERVICE_PORT:-3333}"
     iniset $TEMPEST_CONFIG boto s3_materials_path "$BOTO_MATERIALS_PATH"
     iniset $TEMPEST_CONFIG boto ari_manifest cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-initrd.manifest.xml
@@ -482,7 +484,7 @@
         fi
     done
 
-    if is_ssl_enabled_service "keystone" || is_service_enabled tls-proxy; then
+    if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
         # Use the BOTO_CONFIG environment variable to point to this file
         iniset $BOTO_CONF Boto ca_certificates_file $SSL_BUNDLE_FILE
         sudo chown $STACK_USER $BOTO_CONF
@@ -505,7 +507,7 @@
         # between two regular users in separate tenants
         get_or_create_project alt_demo
         get_or_create_user alt_demo "$ADMIN_PASSWORD" "alt_demo@example.com"
-        get_or_add_user_role Member alt_demo alt_demo
+        get_or_add_user_project_role Member alt_demo alt_demo
     fi
 }
 
diff --git a/lib/trove b/lib/trove
index d32c776..e1b307a 100644
--- a/lib/trove
+++ b/lib/trove
@@ -81,7 +81,7 @@
 function create_trove_accounts {
     if [[ "$ENABLED_SERVICES" =~ "trove" ]]; then
 
-        create_service_user "trove" "admin"
+        create_service_user "trove"
 
         if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
 
diff --git a/lib/zaqar b/lib/zaqar
index 8b560bb..4a24415 100644
--- a/lib/zaqar
+++ b/lib/zaqar
@@ -215,7 +215,7 @@
 }
 
 function create_zaqar_accounts {
-    create_service_user "zaqar" "admin"
+    create_service_user "zaqar"
 
     if [[ "$KEYSTONE_CATALOG_BACKEND" = 'sql' ]]; then
 
diff --git a/stack.sh b/stack.sh
index eaecea0..43cb991 100755
--- a/stack.sh
+++ b/stack.sh
@@ -500,7 +500,6 @@
 # Source project function libraries
 source $TOP_DIR/lib/infra
 source $TOP_DIR/lib/oslo
-source $TOP_DIR/lib/stackforge
 source $TOP_DIR/lib/lvm
 source $TOP_DIR/lib/horizon
 source $TOP_DIR/lib/keystone
@@ -585,7 +584,7 @@
 # The available database backends are listed in ``DATABASE_BACKENDS`` after
 # ``lib/database`` is sourced. ``mysql`` is the default.
 
-initialize_database_backends && echo "Using $DATABASE_TYPE database backend" || die $LINENO "No database enabled"
+initialize_database_backends && echo "Using $DATABASE_TYPE database backend" || echo "No database enabled"
 
 
 # Queue Configuration
@@ -699,11 +698,6 @@
 # Install oslo libraries that have graduated
 install_oslo
 
-# Install stackforge libraries for testing
-if is_service_enabled stackforge_libs; then
-    install_stackforge
-fi
-
 # Install clients libraries
 install_keystoneclient
 install_glanceclient
@@ -1335,57 +1329,6 @@
     echo_summary "WARNING: $DEPRECATED_TEXT"
 fi
 
-if is_service_enabled neutron; then
-    # TODO(dtroyer): Remove Q_AGENT_EXTRA_AGENT_OPTS after stable/juno branch is cut
-    if [[ -n "$Q_AGENT_EXTRA_AGENT_OPTS" ]]; then
-        echo ""
-        echo_summary "WARNING: Q_AGENT_EXTRA_AGENT_OPTS is used"
-        echo "You are using Q_AGENT_EXTRA_AGENT_OPTS to pass configuration into $NEUTRON_CONF."
-        echo "Please convert that configuration in localrc to a $NEUTRON_CONF section in local.conf:"
-        echo "Q_AGENT_EXTRA_AGENT_OPTS will be removed early in the 'K' development cycle"
-        echo "
-[[post-config|/\$Q_PLUGIN_CONF_FILE]]
-[DEFAULT]
-"
-        for I in "${Q_AGENT_EXTRA_AGENT_OPTS[@]}"; do
-            # Replace the first '=' with ' ' for iniset syntax
-            echo ${I}
-        done
-    fi
-
-    # TODO(dtroyer): Remove Q_AGENT_EXTRA_SRV_OPTS after stable/juno branch is cut
-    if [[ -n "$Q_AGENT_EXTRA_SRV_OPTS" ]]; then
-        echo ""
-        echo_summary "WARNING: Q_AGENT_EXTRA_SRV_OPTS is used"
-        echo "You are using Q_AGENT_EXTRA_SRV_OPTS to pass configuration into $NEUTRON_CONF."
-        echo "Please convert that configuration in localrc to a $NEUTRON_CONF section in local.conf:"
-        echo "Q_AGENT_EXTRA_AGENT_OPTS will be removed early in the 'K' development cycle"
-        echo "
-[[post-config|/\$Q_PLUGIN_CONF_FILE]]
-[DEFAULT]
-"
-        for I in "${Q_AGENT_EXTRA_SRV_OPTS[@]}"; do
-            # Replace the first '=' with ' ' for iniset syntax
-            echo ${I}
-        done
-    fi
-fi
-
-if is_service_enabled cinder; then
-    # TODO(dtroyer): Remove CINDER_MULTI_LVM_BACKEND after stable/juno branch is cut
-    if [[ "$CINDER_MULTI_LVM_BACKEND" = "True" ]]; then
-        echo ""
-        echo_summary "WARNING: CINDER_MULTI_LVM_BACKEND is used"
-        echo "You are using CINDER_MULTI_LVM_BACKEND to configure Cinder's multiple LVM backends"
-        echo "Please convert that configuration in local.conf to use CINDER_ENABLED_BACKENDS."
-        echo "CINDER_MULTI_LVM_BACKEND will be removed early in the 'K' development cycle"
-        echo "
-[[local|localrc]]
-CINDER_ENABLED_BACKENDS=lvm:lvmdriver-1,lvm:lvmdriver-2
-"
-    fi
-fi
-
 # Indicate how long this took to run (bash maintained variable ``SECONDS``)
 echo_summary "stack.sh completed in $SECONDS seconds."
 
diff --git a/stackrc b/stackrc
index ff82140..7bbde99 100644
--- a/stackrc
+++ b/stackrc
@@ -55,7 +55,7 @@
 # this allows us to pass ENABLED_SERVICES
 if ! isset ENABLED_SERVICES ; then
     # core compute (glance / keystone / nova (+ nova-network))
-    ENABLED_SERVICES=g-api,g-reg,key,n-api,n-crt,n-obj,n-cpu,n-net,n-cond,n-sch,n-xvnc,n-cauth
+    ENABLED_SERVICES=g-api,g-reg,key,n-api,n-crt,n-obj,n-cpu,n-net,n-cond,n-sch,n-novnc,n-xvnc,n-cauth
     # cinder
     ENABLED_SERVICES+=,c-sch,c-api,c-vol
     # heat
@@ -436,26 +436,6 @@
 
 #################
 #
-#  Additional Libraries
-#
-#################
-
-# stackforge libraries that are used by OpenStack core services
-# wsme
-WSME_REPO=${WSME_REPO:-${GIT_BASE}/stackforge/wsme.git}
-WSME_BRANCH=${WSME_BRANCH:-master}
-
-# pecan
-PECAN_REPO=${PECAN_REPO:-${GIT_BASE}/stackforge/pecan.git}
-PECAN_BRANCH=${PECAN_BRANCH:-master}
-
-# sqlalchemy-migrate
-SQLALCHEMY_MIGRATE_REPO=${SQLALCHEMY_MIGRATE_REPO:-${GIT_BASE}/stackforge/sqlalchemy-migrate.git}
-SQLALCHEMY_MIGRATE_BRANCH=${SQLALCHEMY_MIGRATE_BRANCH:-master}
-
-
-#################
-#
 #  3rd Party Components (non pip installable)
 #
 #  NOTE(sdague): these should be converted to release version installs or removed
diff --git a/tools/create_userrc.sh b/tools/create_userrc.sh
index b43fd88..f067ed1 100755
--- a/tools/create_userrc.sh
+++ b/tools/create_userrc.sh
@@ -131,7 +131,7 @@
 
 EC2_URL=$(openstack endpoint show -f value -c publicurl ec2 || true)
 if [[ -z $EC2_URL ]]; then
-    EC2_URL=http://localhost:8773/services/Cloud
+    EC2_URL=http://localhost:8773/
 fi
 
 S3_URL=$(openstack endpoint show -f value -c publicurl s3 || true)
diff --git a/unstack.sh b/unstack.sh
index b8b7f4a..6deeba2 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -1,4 +1,4 @@
-#!/usr/bin/env bash
+#!/bin/bash
 
 # **unstack.sh**
 
@@ -54,7 +54,6 @@
 # Source project function libraries
 source $TOP_DIR/lib/infra
 source $TOP_DIR/lib/oslo
-source $TOP_DIR/lib/stackforge
 source $TOP_DIR/lib/lvm
 source $TOP_DIR/lib/horizon
 source $TOP_DIR/lib/keystone
@@ -133,13 +132,19 @@
     stop_tls_proxy
     cleanup_CA
 fi
+if [ "$USE_SSL" == "True" ]; then
+    cleanup_CA
+fi
 
 SCSI_PERSIST_DIR=$CINDER_STATE_PATH/volumes/*
 
+# BUG: tgt likes to exit 1 on service stop if everything isn't
+# perfect, we should clean up cinder stop paths.
+
 # Get the iSCSI volumes
 if is_service_enabled cinder; then
-    stop_cinder
-    cleanup_cinder
+    stop_cinder || /bin/true
+    cleanup_cinder || /bin/true
 fi
 
 if [[ -n "$UNSTACK_ALL" ]]; then
@@ -179,4 +184,5 @@
     fi
 fi
 
-clean_lvm_volume_group $DEFAULT_VOLUME_GROUP_NAME
+# BUG: maybe it doesn't exist? We should isolate this further down.
+clean_lvm_volume_group $DEFAULT_VOLUME_GROUP_NAME || /bin/true