Merge "log dstat top io"
diff --git a/extras.d/60-ceph.sh b/extras.d/60-ceph.sh
index 50bdfae..38b901b 100644
--- a/extras.d/60-ceph.sh
+++ b/extras.d/60-ceph.sh
@@ -6,14 +6,19 @@
         source $TOP_DIR/lib/ceph
     elif [[ "$1" == "stack" && "$2" == "pre-install" ]]; then
         echo_summary "Installing Ceph"
-        install_ceph
-        echo_summary "Configuring Ceph"
-        configure_ceph
-        # NOTE (leseb): Do everything here because we need to have Ceph started before the main
-        # OpenStack components. Ceph OSD must start here otherwise we can't upload any images.
-        echo_summary "Initializing Ceph"
-        init_ceph
-        start_ceph
+        check_os_support_ceph
+        if [ "$REMOTE_CEPH" = "False" ]; then
+            install_ceph
+            echo_summary "Configuring Ceph"
+            configure_ceph
+            # NOTE (leseb): Do everything here because we need to have Ceph started before the main
+            # OpenStack components. Ceph OSD must start here otherwise we can't upload any images.
+            echo_summary "Initializing Ceph"
+            init_ceph
+            start_ceph
+        else
+            install_ceph_remote
+        fi
     elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
         if is_service_enabled glance; then
             echo_summary "Configuring Glance for Ceph"
@@ -32,14 +37,39 @@
             echo_summary "Configuring libvirt secret"
             import_libvirt_secret_ceph
         fi
+
+        if [ "$REMOTE_CEPH" = "False" ]; then
+            if is_service_enabled glance; then
+                echo_summary "Configuring Glance for Ceph"
+                configure_ceph_embedded_glance
+            fi
+            if is_service_enabled nova; then
+                echo_summary "Configuring Nova for Ceph"
+                configure_ceph_embedded_nova
+            fi
+            if is_service_enabled cinder; then
+                echo_summary "Configuring Cinder for Ceph"
+                configure_ceph_embedded_cinder
+            fi
+        fi
     fi
 
     if [[ "$1" == "unstack" ]]; then
-        stop_ceph
-        cleanup_ceph
+        if [ "$REMOTE_CEPH" = "True" ]; then
+            cleanup_ceph_remote
+        else
+            cleanup_ceph_embedded
+            stop_ceph
+        fi
+        cleanup_ceph_general
     fi
 
     if [[ "$1" == "clean" ]]; then
-        cleanup_ceph
+        if [ "$REMOTE_CEPH" = "True" ]; then
+            cleanup_ceph_remote
+        else
+            cleanup_ceph_embedded
+        fi
+        cleanup_ceph_general
     fi
 fi
diff --git a/files/debs/neutron b/files/debs/neutron
index fd99677..5a59b22 100644
--- a/files/debs/neutron
+++ b/files/debs/neutron
@@ -1,3 +1,4 @@
+acl     # testonly
 ebtables
 iptables
 iputils-ping
diff --git a/files/rpms-suse/neutron b/files/rpms-suse/neutron
index 8431bd1..50ee145 100644
--- a/files/rpms-suse/neutron
+++ b/files/rpms-suse/neutron
@@ -1,3 +1,4 @@
+acl     # testonly
 dnsmasq
 dnsmasq-utils # dist:opensuse-12.3,opensuse-13.1
 ebtables
diff --git a/files/rpms/neutron b/files/rpms/neutron
index f2473fb..5450408 100644
--- a/files/rpms/neutron
+++ b/files/rpms/neutron
@@ -1,4 +1,5 @@
 MySQL-python
+acl     # testonly
 dnsmasq # for q-dhcp
 dnsmasq-utils # for dhcp_release
 ebtables
diff --git a/functions b/functions
index c7a3b9d..12be160 100644
--- a/functions
+++ b/functions
@@ -42,7 +42,7 @@
     if [[ $image_url != file* ]]; then
         # Downloads the image (uec ami+akistyle), then extracts it.
         if [[ ! -f $FILES/$image_fname || "$(stat -c "%s" $FILES/$image_fname)" = "0" ]]; then
-            wget -c $image_url -O $FILES/$image_fname
+            wget --progress=dot:giga -c $image_url -O $FILES/$image_fname
             if [[ $? -ne 0 ]]; then
                 echo "Not found: $image_url"
                 return
@@ -116,7 +116,7 @@
             if [[ $flat_url != file* ]]; then
                 if [[ ! -f $FILES/$flat_fname || \
                 "$(stat -c "%s" $FILES/$flat_fname)" = "0" ]]; then
-                    wget -c $flat_url -O $FILES/$flat_fname
+                    wget --progress=dot:giga -c $flat_url -O $FILES/$flat_fname
                 fi
                 image="$FILES/${flat_fname}"
             else
diff --git a/functions-common b/functions-common
index 7a6c3a1..b0b2622 100644
--- a/functions-common
+++ b/functions-common
@@ -26,7 +26,6 @@
 # - ``ERROR_ON_CLONE``
 # - ``FILES``
 # - ``OFFLINE``
-# - ``PIP_DOWNLOAD_CACHE``
 # - ``RECLONE``
 # - ``REQUIREMENTS_DIR``
 # - ``STACK_USER``
@@ -1011,7 +1010,6 @@
     fi
     if [[ -z "$DISTRO" ]]; then
         GetDistro
-        echo "Found Distro $DISTRO"
     fi
     for service in ${services//,/ }; do
         # Allow individual services to specify dependencies
@@ -1569,8 +1567,7 @@
 }
 
 # Wrapper for ``pip install`` to set cache and proxy environment variables
-# Uses globals ``OFFLINE``, ``PIP_DOWNLOAD_CACHE``,
-# ``TRACK_DEPENDS``, ``*_proxy``
+# Uses globals ``OFFLINE``, ``TRACK_DEPENDS``, ``*_proxy``
 # pip_install package [package ...]
 function pip_install {
     local xtrace=$(set +o | grep xtrace)
@@ -1595,8 +1592,15 @@
         local sudo_pip="sudo -H"
     fi
 
+    local pip_version=$(python -c "import pip; \
+                        print(pip.__version__.strip('.')[0])")
+    if (( pip_version<6 )); then
+        die $LINENO "Currently installed pip version ${pip_version} does not" \
+            "meet minimum requirements (>=6)."
+    fi
+
     $xtrace
-    $sudo_pip PIP_DOWNLOAD_CACHE=${PIP_DOWNLOAD_CACHE:-/var/cache/pip} \
+    $sudo_pip \
         http_proxy=$http_proxy \
         https_proxy=$https_proxy \
         no_proxy=$no_proxy \
@@ -1607,7 +1611,7 @@
     if [[ "$INSTALL_TESTONLY_PACKAGES" == "True" ]]; then
         local test_req="$@/test-requirements.txt"
         if [[ -e "$test_req" ]]; then
-            $sudo_pip PIP_DOWNLOAD_CACHE=${PIP_DOWNLOAD_CACHE:-/var/cache/pip} \
+            $sudo_pip \
                 http_proxy=$http_proxy \
                 https_proxy=$https_proxy \
                 no_proxy=$no_proxy \
diff --git a/lib/ceph b/lib/ceph
index 3b62a91..77b5726 100644
--- a/lib/ceph
+++ b/lib/ceph
@@ -70,6 +70,11 @@
 CEPH_REPLICAS=${CEPH_REPLICAS:-1}
 CEPH_REPLICAS_SEQ=$(seq ${CEPH_REPLICAS})
 
+# Connect to an existing Ceph cluster
+REMOTE_CEPH=$(trueorfalse False $REMOTE_CEPH)
+REMOTE_CEPH_ADMIN_KEY_PATH=${REMOTE_CEPH_ADMIN_KEY_PATH:-$CEPH_CONF_DIR/ceph.client.admin.keyring}
+
+
 # Functions
 # ------------
 
@@ -94,29 +99,69 @@
     sudo rm -f secret.xml
 }
 
+# undefine_virsh_secret() - Undefine Cinder key secret from libvirt
+function undefine_virsh_secret {
+    if is_service_enabled cinder || is_service_enabled nova; then
+        local virsh_uuid=$(sudo virsh secret-list | awk '/^ ?[0-9a-z]/ { print $1 }')
+        sudo virsh secret-undefine ${virsh_uuid} >/dev/null 2>&1
+    fi
+}
+
+
+# check_os_support_ceph() - Check if the operating system provides a decent version of Ceph
+function check_os_support_ceph {
+    if [[ ! ${DISTRO} =~ (trusty|f20|f21) ]]; then
+        echo "WARNING: your distro $DISTRO does not provide (at least) the Firefly release. Please use Ubuntu Trusty or Fedora 20 (and higher)"
+        if [[ "$FORCE_CEPH_INSTALL" != "yes" ]]; then
+            die $LINENO "If you wish to install Ceph on this distribution anyway run with FORCE_CEPH_INSTALL=yes"
+        fi
+        NO_UPDATE_REPOS=False
+    fi
+}
+
 # cleanup_ceph() - Remove residual data files, anything left over from previous
 # runs that a clean run would need to clean up
-function cleanup_ceph {
+function cleanup_ceph_remote {
+    # do a proper cleanup from here to avoid leftover on the remote Ceph cluster
+    if is_service_enabled glance; then
+        sudo ceph osd pool delete $GLANCE_CEPH_POOL $GLANCE_CEPH_POOL --yes-i-really-really-mean-it > /dev/null 2>&1
+        sudo ceph auth del client.$GLANCE_CEPH_USER > /dev/null 2>&1
+    fi
+    if is_service_enabled cinder; then
+        sudo ceph osd pool delete $CINDER_CEPH_POOL $CINDER_CEPH_POOL --yes-i-really-really-mean-it > /dev/null 2>&1
+        sudo ceph auth del client.$CINDER_CEPH_USER > /dev/null 2>&1
+    fi
+    if is_service_enabled c-bak; then
+        sudo ceph osd pool delete $CINDER_BAK_CEPH_POOL $CINDER_BAK_CEPH_POOL --yes-i-really-really-mean-it > /dev/null 2>&1
+        sudo ceph auth del client.$CINDER_BAK_CEPH_USER > /dev/null 2>&1
+    fi
+    if is_service_enabled nova; then
+        iniset $NOVA_CONF libvirt rbd_secret_uuid ""
+        sudo ceph osd pool delete $NOVA_CEPH_POOL $NOVA_CEPH_POOL --yes-i-really-really-mean-it > /dev/null 2>&1
+    fi
+}
+
+function cleanup_ceph_embedded {
     sudo pkill -f ceph-mon
     sudo pkill -f ceph-osd
     sudo rm -rf ${CEPH_DATA_DIR}/*/*
-    sudo rm -rf ${CEPH_CONF_DIR}/*
     if egrep -q ${CEPH_DATA_DIR} /proc/mounts; then
         sudo umount ${CEPH_DATA_DIR}
     fi
     if [[ -e ${CEPH_DISK_IMAGE} ]]; then
         sudo rm -f ${CEPH_DISK_IMAGE}
     fi
-    uninstall_package ceph ceph-common python-ceph libcephfs1 > /dev/null 2>&1
-    if is_service_enabled cinder || is_service_enabled nova; then
-        local virsh_uuid=$(sudo virsh secret-list | awk '/^ ?[0-9a-z]/ { print $1 }')
-        sudo virsh secret-undefine ${virsh_uuid} >/dev/null 2>&1
-    fi
-    if is_service_enabled nova; then
-        iniset $NOVA_CONF libvirt rbd_secret_uuid ""
-    fi
 }
 
+function cleanup_ceph_general {
+    undefine_virsh_secret
+    uninstall_package ceph ceph-common python-ceph libcephfs1 > /dev/null 2>&1
+
+    # purge ceph config file and keys
+    sudo rm -rf ${CEPH_CONF_DIR}/*
+}
+
+
 # configure_ceph() - Set config files, create data dirs, etc
 function configure_ceph {
     local count=0
@@ -132,7 +177,7 @@
     sudo mkdir /var/lib/ceph/mon/ceph-$(hostname)
 
     # create a default ceph configuration file
-    sudo tee -a ${CEPH_CONF_FILE} > /dev/null <<EOF
+    sudo tee ${CEPH_CONF_FILE} > /dev/null <<EOF
 [global]
 fsid = ${CEPH_FSID}
 mon_initial_members = $(hostname)
@@ -205,14 +250,17 @@
     done
 }
 
-# configure_ceph_glance() - Glance config needs to come after Glance is set up
-function configure_ceph_glance {
+function configure_ceph_embedded_glance {
     # configure Glance service options, ceph pool, ceph user and ceph key
-    sudo ceph -c ${CEPH_CONF_FILE} osd pool create ${GLANCE_CEPH_POOL} ${GLANCE_CEPH_POOL_PG} ${GLANCE_CEPH_POOL_PGP}
     sudo ceph -c ${CEPH_CONF_FILE} osd pool set ${GLANCE_CEPH_POOL} size ${CEPH_REPLICAS}
     if [[ $CEPH_REPLICAS -ne 1 ]]; then
         sudo ceph -c ${CEPH_CONF_FILE} osd pool set ${GLANCE_CEPH_POOL} crush_ruleset ${RULE_ID}
     fi
+}
+
+# configure_ceph_glance() - Glance config needs to come after Glance is set up
+function configure_ceph_glance {
+    sudo ceph -c ${CEPH_CONF_FILE} osd pool create ${GLANCE_CEPH_POOL} ${GLANCE_CEPH_POOL_PG} ${GLANCE_CEPH_POOL_PGP}
     sudo ceph -c ${CEPH_CONF_FILE} auth get-or-create client.${GLANCE_CEPH_USER} mon "allow r" osd "allow class-read object_prefix rbd_children, allow rwx pool=${GLANCE_CEPH_POOL}" | sudo tee ${CEPH_CONF_DIR}/ceph.client.${GLANCE_CEPH_USER}.keyring
     sudo chown ${STACK_USER}:$(id -g -n $whoami) ${CEPH_CONF_DIR}/ceph.client.${GLANCE_CEPH_USER}.keyring
 
@@ -227,14 +275,17 @@
     iniset $GLANCE_API_CONF glance_store rbd_store_pool $GLANCE_CEPH_POOL
 }
 
-# configure_ceph_nova() - Nova config needs to come after Nova is set up
-function configure_ceph_nova {
+function configure_ceph_embedded_nova {
     # configure Nova service options, ceph pool, ceph user and ceph key
-    sudo ceph -c ${CEPH_CONF_FILE} osd pool create ${NOVA_CEPH_POOL} ${NOVA_CEPH_POOL_PG} ${NOVA_CEPH_POOL_PGP}
     sudo ceph -c ${CEPH_CONF_FILE} osd pool set ${NOVA_CEPH_POOL} size ${CEPH_REPLICAS}
     if [[ $CEPH_REPLICAS -ne 1 ]]; then
         sudo -c ${CEPH_CONF_FILE} ceph osd pool set ${NOVA_CEPH_POOL} crush_ruleset ${RULE_ID}
     fi
+}
+
+# configure_ceph_nova() - Nova config needs to come after Nova is set up
+function configure_ceph_nova {
+    sudo ceph -c ${CEPH_CONF_FILE} osd pool create ${NOVA_CEPH_POOL} ${NOVA_CEPH_POOL_PG} ${NOVA_CEPH_POOL_PGP}
     iniset $NOVA_CONF libvirt rbd_user ${CINDER_CEPH_USER}
     iniset $NOVA_CONF libvirt rbd_secret_uuid ${CINDER_CEPH_UUID}
     iniset $NOVA_CONF libvirt inject_key false
@@ -250,15 +301,17 @@
     fi
 }
 
-# configure_ceph_cinder() - Cinder config needs to come after Cinder is set up
-function configure_ceph_cinder {
+function configure_ceph_embedded_cinder {
     # Configure Cinder service options, ceph pool, ceph user and ceph key
-    sudo ceph -c ${CEPH_CONF_FILE} osd pool create ${CINDER_CEPH_POOL} ${CINDER_CEPH_POOL_PG} ${CINDER_CEPH_POOL_PGP}
     sudo ceph -c ${CEPH_CONF_FILE} osd pool set ${CINDER_CEPH_POOL} size ${CEPH_REPLICAS}
     if [[ $CEPH_REPLICAS -ne 1 ]]; then
         sudo ceph -c ${CEPH_CONF_FILE} osd pool set ${CINDER_CEPH_POOL} crush_ruleset ${RULE_ID}
-
     fi
+}
+
+# configure_ceph_cinder() - Cinder config needs to come after Cinder is set up
+function configure_ceph_cinder {
+    sudo ceph -c ${CEPH_CONF_FILE} osd pool create ${CINDER_CEPH_POOL} ${CINDER_CEPH_POOL_PG} ${CINDER_CEPH_POOL_PGP}
     sudo ceph -c ${CEPH_CONF_FILE} auth get-or-create client.${CINDER_CEPH_USER} mon "allow r" osd "allow class-read object_prefix rbd_children, allow rwx pool=${CINDER_CEPH_POOL}, allow rwx pool=${NOVA_CEPH_POOL},allow rx pool=${GLANCE_CEPH_POOL}" | sudo tee ${CEPH_CONF_DIR}/ceph.client.${CINDER_CEPH_USER}.keyring
     sudo chown ${STACK_USER}:$(id -g -n $whoami) ${CEPH_CONF_DIR}/ceph.client.${CINDER_CEPH_USER}.keyring
 }
@@ -272,15 +325,12 @@
 }
 
 # install_ceph() - Collect source and prepare
+function install_ceph_remote {
+    install_package ceph-common
+}
+
 function install_ceph {
-    # NOTE(dtroyer): At some point it'll be easier to test for unsupported distros,
-    #                leveraging the list in stack.sh
-    if [[ ${os_CODENAME} =~ trusty ]] || [[ ${os_CODENAME} =~ Schrödinger’sCat ]] || [[ ${os_CODENAME} =~ Heisenbug ]]; then
-        NO_UPDATE_REPOS=False
-        install_package ceph
-    else
-        exit_distro_not_supported "Ceph since your distro doesn't provide (at least) the Firefly release. Please use Ubuntu Trusty or Fedora 19/20"
-    fi
+    install_package ceph
 }
 
 # start_ceph() - Start running processes, including screen
diff --git a/lib/cinder b/lib/cinder
index c106424..177ddf0 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -110,6 +110,12 @@
     done
 fi
 
+# Change the default nova_catalog_info and nova_catalog_admin_info values in
+# cinder so that the service name cinder is searching for matches that set for
+# nova in keystone.
+CINDER_NOVA_CATALOG_INFO=${CINDER_NOVA_CATALOG_INFO:-compute:nova:publicURL}
+CINDER_NOVA_CATALOG_ADMIN_INFO=${CINDER_NOVA_CATALOG_ADMIN_INFO:-compute:nova:adminURL}
+
 
 # Functions
 # ---------
@@ -205,6 +211,8 @@
 
     cp -p $CINDER_DIR/etc/cinder/policy.json $CINDER_CONF_DIR
 
+    rm -f $CINDER_CONF
+
     configure_cinder_rootwrap
 
     cp $CINDER_DIR/etc/cinder/api-paste.ini $CINDER_API_PASTE_INI
@@ -220,6 +228,9 @@
 
     configure_auth_token_middleware $CINDER_CONF cinder $CINDER_AUTH_CACHE_DIR
 
+    iniset $CINDER_CONF DEFAULT nova_catalog_info $CINDER_NOVA_CATALOG_INFO
+    iniset $CINDER_CONF DEFAULT nova_catalog_admin_info $CINDER_NOVA_CATALOG_ADMIN_INFO
+
     iniset $CINDER_CONF DEFAULT auth_strategy keystone
     iniset $CINDER_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
     iniset $CINDER_CONF DEFAULT verbose True
diff --git a/lib/cinder_backends/ceph b/lib/cinder_backends/ceph
index 415ce94..7e9d2d3 100644
--- a/lib/cinder_backends/ceph
+++ b/lib/cinder_backends/ceph
@@ -54,11 +54,13 @@
     iniset $CINDER_CONF DEFAULT glance_api_version 2
 
     if is_service_enabled c-bak; then
-        # Configure Cinder backup service options, ceph pool, ceph user and ceph key
         sudo ceph -c ${CEPH_CONF_FILE} osd pool create ${CINDER_BAK_CEPH_POOL} ${CINDER_BAK_CEPH_POOL_PG} ${CINDER_BAK_CEPH_POOL_PGP}
-        sudo ceph -c ${CEPH_CONF_FILE} osd pool set ${CINDER_BAK_CEPH_POOL} size ${CEPH_REPLICAS}
-        if [[ $CEPH_REPLICAS -ne 1 ]]; then
-            sudo ceph -c ${CEPH_CONF_FILE} osd pool set ${CINDER_BAK_CEPH_POOL} crush_ruleset ${RULE_ID}
+        if [ "$REMOTE_CEPH" = "False" ]; then
+            # Configure Cinder backup service options, ceph pool, ceph user and ceph key
+            sudo ceph -c ${CEPH_CONF_FILE} osd pool set ${CINDER_BAK_CEPH_POOL} size ${CEPH_REPLICAS}
+            if [[ $CEPH_REPLICAS -ne 1 ]]; then
+                sudo ceph -c ${CEPH_CONF_FILE} osd pool set ${CINDER_BAK_CEPH_POOL} crush_ruleset ${RULE_ID}
+            fi
         fi
         sudo ceph -c ${CEPH_CONF_FILE} auth get-or-create client.${CINDER_BAK_CEPH_USER} mon "allow r" osd "allow class-read object_prefix rbd_children, allow rwx pool=${CINDER_BAK_CEPH_POOL}" | sudo tee ${CEPH_CONF_DIR}/ceph.client.${CINDER_BAK_CEPH_USER}.keyring
         sudo chown $(whoami):$(whoami) ${CEPH_CONF_DIR}/ceph.client.${CINDER_BAK_CEPH_USER}.keyring
diff --git a/lib/databases/mysql b/lib/databases/mysql
index d39d966..62c3d4c 100644
--- a/lib/databases/mysql
+++ b/lib/databases/mysql
@@ -23,22 +23,27 @@
     if is_ubuntu; then
         # Get ruthless with mysql
         stop_service $MYSQL
-        apt_get purge -y mysql*
+        uninstall_package mysql-common mariadb-common
         sudo rm -rf /var/lib/mysql
         sudo rm -rf /etc/mysql
         return
     elif is_fedora; then
         if [[ $DISTRO =~ (rhel6) ]]; then
-            MYSQL=mysqld
+            stop_service mysqld
+            uninstall_package mysql-server
+            sudo rm -rf /var/lib/mysql
         else
-            MYSQL=mariadb
+            stop_service mariadb
+            uninstall_package mariadb-server
+            sudo rm -rf /var/lib/mysql
         fi
     elif is_suse; then
-        MYSQL=mysql
+        stop_service mysql
+        uninstall_package mysql-community-server
+        sudo rm -rf /var/lib/mysql
     else
         return
     fi
-    stop_service $MYSQL
 }
 
 function recreate_database_mysql {
diff --git a/lib/heat b/lib/heat
index 4e72cae..544ec45 100644
--- a/lib/heat
+++ b/lib/heat
@@ -38,6 +38,7 @@
 HEAT_TEMPLATES_REPO_DIR=$DEST/heat-templates
 HEAT_AUTH_CACHE_DIR=${HEAT_AUTH_CACHE_DIR:-/var/cache/heat}
 HEAT_STANDALONE=`trueorfalse False $HEAT_STANDALONE`
+HEAT_ENABLE_ADOPT_ABANDON=`trueorfalse False $HEAT_ENABLE_ADOPT_ABANDON`
 HEAT_CONF_DIR=/etc/heat
 HEAT_CONF=$HEAT_CONF_DIR/heat.conf
 HEAT_ENV_DIR=$HEAT_CONF_DIR/environment.d
@@ -151,6 +152,11 @@
         iniset $HEAT_CONF clients_cinder ca_file $SSL_BUNDLE_FILE
     fi
 
+    if [[ "$HEAT_ENABLE_ADOPT_ABANDON" = "True" ]]; then
+        iniset $HEAT_CONF DEFAULT enable_stack_adopt true
+        iniset $HEAT_CONF DEFAULT enable_stack_abandon true
+    fi
+
     # heat environment
     sudo mkdir -p $HEAT_ENV_DIR
     sudo chown $STACK_USER $HEAT_ENV_DIR
diff --git a/lib/neutron b/lib/neutron
index 5678769..b4d0b8c 100755
--- a/lib/neutron
+++ b/lib/neutron
@@ -908,7 +908,7 @@
     Q_L3_ROUTER_PER_TENANT=$Q_USE_NAMESPACE
 
     if is_service_enabled q-vpn; then
-        cp $NEUTRON_DIR/etc/vpn_agent.ini $Q_VPN_CONF_FILE
+        cp $NEUTRON_VPNAAS_DIR/etc/vpn_agent.ini $Q_VPN_CONF_FILE
     fi
 
     cp $NEUTRON_DIR/etc/l3_agent.ini $Q_L3_CONF_FILE
@@ -1034,22 +1034,28 @@
     fi
 }
 
+# _neutron_deploy_rootwrap_filters() - deploy rootwrap filters to $Q_CONF_ROOTWRAP_D (owned by root).
+function _neutron_deploy_rootwrap_filters {
+    local srcdir=$1
+    mkdir -p -m 755 $Q_CONF_ROOTWRAP_D
+    sudo cp -pr $srcdir/etc/neutron/rootwrap.d/* $Q_CONF_ROOTWRAP_D/
+    sudo chown -R root:root $Q_CONF_ROOTWRAP_D
+    sudo chmod 644 $Q_CONF_ROOTWRAP_D/*
+}
+
 # _neutron_setup_rootwrap() - configure Neutron's rootwrap
 function _neutron_setup_rootwrap {
     if [[ "$Q_USE_ROOTWRAP" == "False" ]]; then
         return
     fi
-    # Deploy new rootwrap filters files (owned by root).
     # Wipe any existing ``rootwrap.d`` files first
     Q_CONF_ROOTWRAP_D=$NEUTRON_CONF_DIR/rootwrap.d
     if [[ -d $Q_CONF_ROOTWRAP_D ]]; then
         sudo rm -rf $Q_CONF_ROOTWRAP_D
     fi
-    # Deploy filters to ``$NEUTRON_CONF_DIR/rootwrap.d``
-    mkdir -p -m 755 $Q_CONF_ROOTWRAP_D
-    cp -pr $NEUTRON_DIR/etc/neutron/rootwrap.d/* $Q_CONF_ROOTWRAP_D/
-    sudo chown -R root:root $Q_CONF_ROOTWRAP_D
-    sudo chmod 644 $Q_CONF_ROOTWRAP_D/*
+
+    _neutron_deploy_rootwrap_filters $NEUTRON_DIR
+
     # Set up ``rootwrap.conf``, pointing to ``$NEUTRON_CONF_DIR/rootwrap.d``
     # location moved in newer versions, prefer new location
     if test -r $NEUTRON_DIR/etc/neutron/rootwrap.conf; then
diff --git a/lib/neutron_plugins/services/firewall b/lib/neutron_plugins/services/firewall
index a1c13ed..61a148e 100644
--- a/lib/neutron_plugins/services/firewall
+++ b/lib/neutron_plugins/services/firewall
@@ -13,7 +13,7 @@
 
 function neutron_fwaas_configure_driver {
     FWAAS_DRIVER_CONF_FILENAME=/etc/neutron/fwaas_driver.ini
-    cp $NEUTRON_DIR/etc/fwaas_driver.ini $FWAAS_DRIVER_CONF_FILENAME
+    cp $NEUTRON_FWAAS_DIR/etc/fwaas_driver.ini $FWAAS_DRIVER_CONF_FILENAME
 
     iniset_multiline $FWAAS_DRIVER_CONF_FILENAME fwaas enabled True
     iniset_multiline $FWAAS_DRIVER_CONF_FILENAME fwaas driver "neutron_fwaas.services.firewall.drivers.linux.iptables_fwaas.IptablesFwaasDriver"
diff --git a/lib/neutron_plugins/services/loadbalancer b/lib/neutron_plugins/services/loadbalancer
index bd9dc87..f465cc9 100644
--- a/lib/neutron_plugins/services/loadbalancer
+++ b/lib/neutron_plugins/services/loadbalancer
@@ -17,6 +17,7 @@
 
 function neutron_agent_lbaas_configure_common {
     _neutron_service_plugin_class_add $LBAAS_PLUGIN
+    _neutron_deploy_rootwrap_filters $NEUTRON_LBAAS_DIR
 }
 
 function neutron_agent_lbaas_configure_agent {
@@ -25,7 +26,7 @@
 
     LBAAS_AGENT_CONF_FILENAME="$LBAAS_AGENT_CONF_PATH/lbaas_agent.ini"
 
-    cp $NEUTRON_DIR/etc/lbaas_agent.ini $LBAAS_AGENT_CONF_FILENAME
+    cp $NEUTRON_LBAAS_DIR/etc/lbaas_agent.ini $LBAAS_AGENT_CONF_FILENAME
 
     # ovs_use_veth needs to be set before the plugin configuration
     # occurs to allow plugins to override the setting.
diff --git a/lib/neutron_plugins/services/vpn b/lib/neutron_plugins/services/vpn
index 07f1f35..7e80b5b 100644
--- a/lib/neutron_plugins/services/vpn
+++ b/lib/neutron_plugins/services/vpn
@@ -16,6 +16,7 @@
 
 function neutron_vpn_configure_common {
     _neutron_service_plugin_class_add $VPN_PLUGIN
+    _neutron_deploy_rootwrap_filters $NEUTRON_VPNAAS_DIR
 }
 
 function neutron_vpn_stop {
diff --git a/lib/nova b/lib/nova
index cbfbdfa..5ac9ff1 100644
--- a/lib/nova
+++ b/lib/nova
@@ -769,8 +769,8 @@
 }
 
 function start_nova {
-    start_nova_compute
     start_nova_rest
+    start_nova_compute
 }
 
 function stop_nova_compute {
diff --git a/lib/rpc_backend b/lib/rpc_backend
index 172d024..778d466 100644
--- a/lib/rpc_backend
+++ b/lib/rpc_backend
@@ -87,11 +87,20 @@
         fi
     elif is_service_enabled zeromq; then
         if is_fedora; then
-            uninstall_package zeromq python-zmq redis
+            uninstall_package zeromq python-zmq
+            if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
+                uninstall_package redis python-redis
+            fi
         elif is_ubuntu; then
-            uninstall_package libzmq1 python-zmq redis-server
+            uninstall_package libzmq1 python-zmq
+            if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
+                uninstall_package redis-server python-redis
+            fi
         elif is_suse; then
-            uninstall_package libzmq1 python-pyzmq redis
+            uninstall_package libzmq1 python-pyzmq
+            if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
+                uninstall_package redis python-redis
+            fi
         else
             exit_distro_not_supported "zeromq installation"
         fi
@@ -150,11 +159,20 @@
         # but there is a matchmaker driver that works
         # really well & out of the box for multi-node.
         if is_fedora; then
-            install_package zeromq python-zmq redis
+            install_package zeromq python-zmq
+            if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
+                install_package redis python-redis
+            fi
         elif is_ubuntu; then
-            install_package libzmq1 python-zmq redis-server
+            install_package libzmq1 python-zmq
+            if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
+                install_package redis-server python-redis
+            fi
         elif is_suse; then
-            install_package libzmq1 python-pyzmq redis
+            install_package libzmq1 python-pyzmq
+            if [ "$ZEROMQ_MATCHMAKER" == "redis" ]; then
+                install_package redis python-redis
+            fi
         else
             exit_distro_not_supported "zeromq installation"
         fi
diff --git a/stack.sh b/stack.sh
index b064c22..696dc24 100755
--- a/stack.sh
+++ b/stack.sh
@@ -143,7 +143,7 @@
 
 # Warn users who aren't on an explicitly supported distro, but allow them to
 # override check and attempt installation with ``FORCE=yes ./stack``
-if [[ ! ${DISTRO} =~ (precise|trusty|7.0|wheezy|sid|testing|jessie|f19|f20|f21|rhel6|rhel7) ]]; then
+if [[ ! ${DISTRO} =~ (precise|trusty|7.0|wheezy|sid|testing|jessie|f20|f21|rhel6|rhel7) ]]; then
     echo "WARNING: this script has not been tested on $DISTRO"
     if [[ "$FORCE" != "yes" ]]; then
         die $LINENO "If you wish to run this script anyway run with FORCE=yes"
@@ -1030,6 +1030,14 @@
 fi
 
 
+# ZeroMQ
+# ------
+if is_service_enabled zeromq; then
+    echo_summary "Starting zeromq receiver"
+    run_process zeromq "$OSLO_BIN_DIR/oslo-messaging-zmq-receiver"
+fi
+
+
 # Horizon
 # -------
 
@@ -1208,11 +1216,6 @@
     iniset $NOVA_CONF keymgr fixed_key $(generate_hex_string 32)
 fi
 
-if is_service_enabled zeromq; then
-    echo_summary "Starting zermomq receiver"
-    run_process zeromq "$OSLO_BIN_DIR/oslo-messaging-zmq-receiver"
-fi
-
 # Launch the nova-api and wait for it to answer before continuing
 if is_service_enabled n-api; then
     echo_summary "Starting Nova API"
diff --git a/stackrc b/stackrc
index be27dce..355c0dc 100644
--- a/stackrc
+++ b/stackrc
@@ -33,7 +33,8 @@
 # For example, to enable Swift add this to ``local.conf``:
 #  enable_service s-proxy s-object s-container s-account
 # In order to enable Neutron (a single node setup) add the following
-# settings in `` localrc``:
+# settings in ``local.conf``:
+#  [[local|localrc]]
 #  disable_service n-net
 #  enable_service q-svc
 #  enable_service q-agt
@@ -529,8 +530,8 @@
 CIRROS_ARCH=${CIRROS_ARCH:-"x86_64"}
 
 # Set default image based on ``VIRT_DRIVER`` and ``LIBVIRT_TYPE``, either of
-# which may be set in ``localrc``.  Also allow ``DEFAULT_IMAGE_NAME`` and
-# ``IMAGE_URLS`` to be set directly in ``localrc``.
+# which may be set in ``local.conf``.  Also allow ``DEFAULT_IMAGE_NAME`` and
+# ``IMAGE_URLS`` to be set in the `localrc` section of ``local.conf``.
 case "$VIRT_DRIVER" in
     openvz)
         DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-ubuntu-12.04-x86_64}
diff --git a/tools/fixup_stuff.sh b/tools/fixup_stuff.sh
index 26aae82..c7f1efa 100755
--- a/tools/fixup_stuff.sh
+++ b/tools/fixup_stuff.sh
@@ -111,8 +111,8 @@
     fi
 
     FORCE_FIREWALLD=$(trueorfalse False $FORCE_FIREWALLD)
-    if [[ ${DISTRO} =~ (f19|f20) && $FORCE_FIREWALLD == "False" ]]; then
-        # On Fedora 19 and 20 firewalld interacts badly with libvirt and
+    if [[ ${DISTRO} =~ (f20) && $FORCE_FIREWALLD == "False" ]]; then
+        # On Fedora 20 firewalld interacts badly with libvirt and
         # slows things down significantly.  However, for those cases
         # where that combination is desired, allow this fix to be skipped.