Merge "Do not pass -U to useradd"
diff --git a/.gitignore b/.gitignore
index 83c5419..c5744b3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,6 +2,10 @@
 *~
 .*.sw[nop]
 *.log
+*.log.[1-9]
 src
 localrc
 local.sh
+files/*.gz
+files/images
+stack-screenrc
diff --git a/AUTHORS b/AUTHORS
index b5f972f..6141d67 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,4 +1,5 @@
 Aaron Lee <aaron.lee@rackspace.com>
+Aaron Rosen <arosen@nicira.com>
 Adam Gandelman <adamg@canonical.com>
 Andy Smith <github@anarkystic.com>
 Anthony Young <sleepsonthefloor@gmail.com>
@@ -8,9 +9,12 @@
 Dan Prince <dprince@redhat.com>
 Dean Troyer <dtroyer@gmail.com>
 Devin Carlen <devin.carlen@gmail.com>
+Doug hellmann <doug.hellmann@dreamhost.com>
 Eddie Hebert <edhebert@gmail.com>
 Eoghan Glynn <eglynn@redhat.com>
+Eric Windisch <ewindisch@cloudscaling.com>
 Gabriel Hurley <gabriel@strikeawe.com>
+Gary Kotton <gkotton@redhat.com>
 Hengqing Hu <hudayou@hotmail.com>
 Hua ZHANG <zhuadl@cn.ibm.com>
 Jake Dahn <admin@jakedahn.com>
diff --git a/README.md b/README.md
index cfcfe7c..fd66e96 100644
--- a/README.md
+++ b/README.md
@@ -61,15 +61,16 @@
 
 Swift is not installed by default, you can enable easily by adding this to your `localrc`:
 
-    ENABLED_SERVICE="$ENABLED_SERVICES,swift"
+    enable_service swift
 
 If you want a minimal Swift install with only Swift and Keystone you can have this instead in your `localrc`:
 
-    ENABLED_SERVICES="key,mysql,swift"
+    disable_all_services
+    enable_service key mysql swift
 
 If you use Swift with Keystone, Swift will authenticate against it. You will need to make sure to use the Keystone URL to auth against.
 
-Swift will be acting as a S3 endpoint for Keystone so effectively replacing the `nova-objectstore`.
+If you are enabling `swift3` in `ENABLED_SERVICES` devstack will install the swift3 middleware emulation. Swift will be configured to act as a S3 endpoint for Keystone so effectively replacing the `nova-objectstore`.
 
 Only Swift proxy server is launched in the screen session all other services are started in background and managed by `swift-init` tool.
 
diff --git a/exercise.sh b/exercise.sh
index 15f264f..a0349ce 100755
--- a/exercise.sh
+++ b/exercise.sh
@@ -5,6 +5,9 @@
 # Keep track of the current devstack directory.
 TOP_DIR=$(cd $(dirname "$0") && pwd)
 
+# Import common functions
+source $TOP_DIR/functions
+
 # Load local configuration
 source $TOP_DIR/stackrc
 
diff --git a/exercises/bundle.sh b/exercises/bundle.sh
index c607c94..daff5f9 100755
--- a/exercises/bundle.sh
+++ b/exercises/bundle.sh
@@ -17,6 +17,7 @@
 # an error.  It is also useful for following allowing as the install occurs.
 set -o xtrace
 
+
 # Settings
 # ========
 
diff --git a/exercises/client-args.sh b/exercises/client-args.sh
index 1d7d5b6..39241a2 100755
--- a/exercises/client-args.sh
+++ b/exercises/client-args.sh
@@ -1,11 +1,14 @@
 #!/usr/bin/env bash
 
+**client-args.sh**
+
 # Test OpenStack client authentication aguemnts handling
 
 echo "*********************************************************************"
 echo "Begin DevStack Exercise: $0"
 echo "*********************************************************************"
 
+
 # Settings
 # ========
 
@@ -38,7 +41,7 @@
 export x_PASSWORD=$OS_PASSWORD
 export x_AUTH_URL=$OS_AUTH_URL
 
-#Unset the usual variables to force argument processing
+# Unset the usual variables to force argument processing
 unset OS_TENANT_NAME
 unset OS_USERNAME
 unset OS_PASSWORD
@@ -113,7 +116,7 @@
         STATUS_SWIFT="Skipped"
     else
         echo -e "\nTest Swift"
-        if swift $ARGS stat; then
+        if swift $TENANT_ARG $ARGS stat; then
             STATUS_SWIFT="Succeeded"
         else
             STATUS_SWIFT="Failed"
diff --git a/exercises/client-env.sh b/exercises/client-env.sh
index 10871a6..d242ee5 100755
--- a/exercises/client-env.sh
+++ b/exercises/client-env.sh
@@ -1,13 +1,13 @@
 #!/usr/bin/env bash
 
+**client-env.sh**
+
 # Test OpenStack client enviroment variable handling
 
 echo "*********************************************************************"
 echo "Begin DevStack Exercise: $0"
 echo "*********************************************************************"
 
-# Verify client workage
-VERIFY=${1:-""}
 
 # Settings
 # ========
diff --git a/exercises/floating_ips.sh b/exercises/floating_ips.sh
index 82f29eb..51019a3 100755
--- a/exercises/floating_ips.sh
+++ b/exercises/floating_ips.sh
@@ -83,7 +83,7 @@
     fi
 fi
 
-# determinine instance type
+# Determinine instance type
 # -------------------------
 
 # List of instance types:
@@ -100,6 +100,7 @@
 VM_UUID=`nova boot --flavor $INSTANCE_TYPE --image $IMAGE $NAME --security_groups=$SECGROUP | grep ' id ' | get_field 2`
 die_if_not_set VM_UUID "Failure launching $NAME"
 
+
 # Testing
 # =======
 
diff --git a/exercises/swift.sh b/exercises/swift.sh
index 732445d..4cd487b 100755
--- a/exercises/swift.sh
+++ b/exercises/swift.sh
@@ -40,6 +40,7 @@
 # exercise is skipped.
 is_service_enabled swift || exit 55
 
+
 # Testing Swift
 # =============
 
diff --git a/files/apts/general b/files/apts/general
index 31fa752..be7bf98 100644
--- a/files/apts/general
+++ b/files/apts/general
@@ -1,3 +1,4 @@
+bridge-utils
 pep8
 pylint
 python-pip
@@ -17,3 +18,5 @@
 curl
 tcpdump
 euca2ools # only for testing client
+tar
+python-cmd2 # dist:precise
diff --git a/files/horizon_settings.py b/files/horizon_settings.py
index 1a6c17a..487c06e 100644
--- a/files/horizon_settings.py
+++ b/files/horizon_settings.py
@@ -20,6 +20,10 @@
 CACHE_BACKEND = 'dummy://'
 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db'
 
+# Set a secure and unique SECRET_KEY (the Django default is '')
+from horizon.utils import secret_key
+SECRET_KEY = secret_key.generate_or_read_from_file(os.path.join(LOCAL_PATH, '.secret_key_store'))
+
 # Send email to the console by default
 EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
 # Or send them to /dev/null
diff --git a/files/keystone_data.sh b/files/keystone_data.sh
index ba14a47..6987797 100755
--- a/files/keystone_data.sh
+++ b/files/keystone_data.sh
@@ -275,7 +275,7 @@
         --role_id $MEMBER_ROLE
 fi
 
-if [[ "$ENABLED_SERVICES" =~ "cinder" ]]; then
+if [[ "$ENABLED_SERVICES" =~ "c-api" ]]; then
     CINDER_USER=$(get_id keystone user-create --name=cinder \
                                               --pass="$SERVICE_PASSWORD" \
                                               --tenant_id $SERVICE_TENANT \
diff --git a/files/rpms/general b/files/rpms/general
index af199d5..6d89d2e 100644
--- a/files/rpms/general
+++ b/files/rpms/general
@@ -1,3 +1,4 @@
+bridge-utils
 curl
 euca2ools # only for testing client
 git-core
@@ -9,6 +10,7 @@
 python-unittest2
 python-virtualenv
 screen
+tar
 tcpdump
 unzip
 wget
diff --git a/functions b/functions
index 8cf7c74..b66dc15 100644
--- a/functions
+++ b/functions
@@ -1,3 +1,4 @@
+# -*- mode: Shell-script -*-
 # functions - Common functions used by DevStack components
 #
 # ENABLED_SERVICES is used by is_service_enabled()
@@ -223,6 +224,24 @@
 }
 
 
+# Translate the OS version values into common nomenclature
+# Sets ``DISTRO`` from the ``os_*`` values
+function GetDistro() {
+    GetOSVersion
+    if [[ "$os_VENDOR" =~ (Ubuntu) ]]; then
+        # 'Everyone' refers to Ubuntu releases by the code name adjective
+        DISTRO=$os_CODENAME
+    elif [[ "$os_VENDOR" =~ (Fedora) ]]; then
+        # For Fedora, just use 'f' and the release
+        DISTRO="f$os_RELEASE"
+    else
+        # Catch-all for now is Vendor + Release + Update
+        DISTRO="$os_VENDOR-$os_RELEASE.$os_UPDATE"
+    fi
+    export DISTRO
+}
+
+
 # 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.
@@ -349,6 +368,76 @@
     return 1
 }
 
+# remove extra commas from the input string (ENABLED_SERVICES)
+function _cleanup_service_list () {
+	echo "$1" | sed -e '
+        s/,,/,/g;
+        s/^,//;
+        s/,$//
+    '
+}
+
+# enable_service() adds the services passed as argument to the
+# **ENABLED_SERVICES** list, if they are not already present.
+#
+# For example:
+#
+#   enable_service n-vol
+#
+# This function does not know about the special cases
+# for nova, glance, and quantum built into is_service_enabled().
+function enable_service() {
+    local tmpsvcs="${ENABLED_SERVICES}"
+    for service in $@; do
+        if ! is_service_enabled $service; then
+            tmpsvcs+=",$service"
+        fi
+    done
+    ENABLED_SERVICES=$(_cleanup_service_list "$tmpsvcs")
+    disable_negated_services
+}
+
+# disable_service() removes the services passed as argument to the
+# **ENABLED_SERVICES** list, if they are present.
+#
+# For example:
+#
+#   disable_service n-vol
+#
+# This function does not know about the special cases
+# for nova, glance, and quantum built into is_service_enabled().
+function disable_service() {
+    local tmpsvcs=",${ENABLED_SERVICES},"
+    local service
+    for service in $@; do
+        if is_service_enabled $service; then
+            tmpsvcs=${tmpsvcs//,$service,/,}
+        fi
+    done
+    ENABLED_SERVICES=$(_cleanup_service_list "$tmpsvcs")
+}
+
+# disable_all_services() removes all current services
+# from **ENABLED_SERVICES** to reset the configuration
+# before a minimal installation
+function disable_all_services() {
+    ENABLED_SERVICES=""
+}
+
+# We are looking for services with a - at the beginning to force
+# excluding those services. For example if you want to install all the default
+# services but not nova-volume (n-vol) you can have this set in your localrc :
+# ENABLED_SERVICES+=",-n-vol"
+function disable_negated_services() {
+    local tmpsvcs="${ENABLED_SERVICES}"
+    local service
+    for service in ${tmpsvcs//,/ }; do
+        if [[ ${service} == -* ]]; then
+            tmpsvcs=$(echo ${tmpsvcs}|sed -r "s/(,)?(-)?${service#-}(,)?/,/g")
+        fi
+    done
+    ENABLED_SERVICES=$(_cleanup_service_list "$tmpsvcs")
+}
 
 # Distro-agnostic package installer
 # install_package package [package ...]
@@ -382,12 +471,19 @@
     if [[ -z "$os_PACKAGE" ]]; then
         GetOSVersion
     fi
-    if [[ "$os_PACKAGE" = "deb" ]]; then
-        CMD_PIP=/usr/bin/pip
+    if [[ $TRACK_DEPENDS = True ]] ; then
+        source $DEST/.venv/bin/activate
+        CMD_PIP=$DEST/.venv/bin/pip
+        SUDO_PIP="env"
     else
-        CMD_PIP=/usr/bin/pip-python
+        SUDO_PIP="sudo"
+        if [[ "$os_PACKAGE" = "deb" ]]; then
+            CMD_PIP=/usr/bin/pip
+        else
+            CMD_PIP=/usr/bin/pip-python
+        fi
     fi
-    sudo PIP_DOWNLOAD_CACHE=/var/cache/pip \
+    $SUDO_PIP PIP_DOWNLOAD_CACHE=${PIP_DOWNLOAD_CACHE:-/var/cache/pip} \
         HTTP_PROXY=$http_proxy \
         HTTPS_PROXY=$https_proxy \
         $CMD_PIP install --use-mirrors $@
@@ -412,12 +508,17 @@
 # develop, so that pip and not distutils process the dependency chain
 # setup_develop directory
 function setup_develop() {
+    if [[ $TRACK_DEPENDS = True ]] ; then
+        SUDO_CMD="env"
+    else
+        SUDO_CMD="sudo"
+    fi
     (cd $1; \
         python setup.py egg_info; \
         raw_links=$(awk '/^.+/ {print "-f " $1}' *.egg-info/dependency_links.txt); \
         depend_links=$(echo $raw_links | xargs); \
         pip_install -r *-info/requires.txt $depend_links; \
-        sudo \
+        $SUDO_CMD \
             HTTP_PROXY=$http_proxy \
             HTTPS_PROXY=$https_proxy \
             python setup.py develop \
diff --git a/lib/cinder b/lib/cinder
index f0715a4..49ad4af 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -52,6 +52,42 @@
 
     cp -p $CINDER_DIR/etc/cinder/policy.json $CINDER_CONF_DIR
 
+    # Set the paths of certain binaries
+    if [[ "$os_PACKAGE" = "deb" ]]; then
+        CINDER_ROOTWRAP=/usr/local/bin/cinder-rootwrap
+    else
+        CINDER_ROOTWRAP=/usr/bin/cinder-rootwrap
+    fi
+
+    # If Cinder ships the new rootwrap filters files, deploy them
+    # (owned by root) and add a parameter to $CINDER_ROOTWRAP
+    ROOTWRAP_CINDER_SUDOER_CMD="$CINDER_ROOTWRAP"
+    if [[ -d $CINDER_DIR/etc/cinder/rootwrap.d ]]; then
+        # Wipe any existing rootwrap.d files first
+        if [[ -d $CINDER_CONF_DIR/rootwrap.d ]]; then
+            sudo rm -rf $CINDER_CONF_DIR/rootwrap.d
+        fi
+        # Deploy filters to /etc/cinder/rootwrap.d
+        sudo mkdir -m 755 $CINDER_CONF_DIR/rootwrap.d
+        sudo cp $CINDER_DIR/etc/cinder/rootwrap.d/*.filters $CINDER_CONF_DIR/rootwrap.d
+        sudo chown -R root:root $CINDER_CONF_DIR/rootwrap.d
+        sudo chmod 644 $CINDER_CONF_DIR/rootwrap.d/*
+        # Set up rootwrap.conf, pointing to /etc/cinder/rootwrap.d
+        sudo cp $CINDER_DIR/etc/cinder/rootwrap.conf $CINDER_CONF_DIR/
+        sudo sed -e "s:^filters_path=.*$:filters_path=$CINDER_CONF_DIR/rootwrap.d:" -i $CINDER_CONF_DIR/rootwrap.conf
+        sudo chown root:root $CINDER_CONF_DIR/rootwrap.conf
+        sudo chmod 0644 $CINDER_CONF_DIR/rootwrap.conf
+        # Specify rootwrap.conf as first parameter to cinder-rootwrap
+        CINDER_ROOTWRAP="$CINDER_ROOTWRAP $CINDER_CONF_DIR/rootwrap.conf"
+        ROOTWRAP_CINDER_SUDOER_CMD="$CINDER_ROOTWRAP *"
+    fi
+
+    TEMPFILE=`mktemp`
+    echo "$USER ALL=(root) NOPASSWD: $ROOTWRAP_CINDER_SUDOER_CMD" >$TEMPFILE
+    chmod 0440 $TEMPFILE
+    sudo chown root:root $TEMPFILE
+    sudo mv $TEMPFILE /etc/sudoers.d/cinder-rootwrap
+
     CINDER_API_PASTE_INI=$CINDER_CONF_DIR/api-paste.ini
     cp $CINDER_DIR/etc/cinder/api-paste.ini $CINDER_API_PASTE_INI
     iniset $CINDER_API_PASTE_INI filter:authtoken auth_host $KEYSTONE_AUTH_HOST
@@ -71,6 +107,8 @@
     iniset $CINDER_CONF DEFAULT rabbit_host $RABBIT_HOST
     iniset $CINDER_CONF DEFAULT rabbit_password $RABBIT_PASSWORD
     iniset $CINDER_CONF DEFAULT api_paste_config $CINDER_API_PASTE_INI
+    iniset $CINDER_CONF DEFAULT root_helper "sudo ${CINDER_ROOTWRAP}"
+
 }
 
 # init_cinder() - Initialize database and volume group
@@ -93,11 +131,10 @@
         # volume group, create your own volume group called ``stack-volumes`` before
         # invoking ``stack.sh``.
         #
-        # By default, the backing file is 2G in size, and is stored in ``/opt/stack/data``.
+        # By default, the backing file is 5G in size, and is stored in ``/opt/stack/data``.
 
         if ! sudo vgs $VOLUME_GROUP; then
             VOLUME_BACKING_FILE=${VOLUME_BACKING_FILE:-$DATA_DIR/${VOLUME_GROUP}-backing-file}
-            VOLUME_BACKING_FILE_SIZE=${VOLUME_BACKING_FILE_SIZE:-2052M}
             # Only create if the file doesn't already exists
             [[ -f $VOLUME_BACKING_FILE ]] || truncate -s $VOLUME_BACKING_FILE_SIZE $VOLUME_BACKING_FILE
             DEV=`sudo losetup -f --show $VOLUME_BACKING_FILE`
@@ -105,7 +142,14 @@
             if ! sudo vgs $VOLUME_GROUP; then sudo vgcreate $VOLUME_GROUP $DEV; fi
         fi
 
+        mkdir -p $CINDER_DIR/volumes
+
         if sudo vgs $VOLUME_GROUP; then
+            if [[ "$os_PACKAGE" = "rpm" ]]; then
+                # RPM doesn't start the service
+                start_service tgtd
+            fi
+
             # Remove iscsi targets
             sudo tgtadm --op show --mode target | grep $VOLUME_NAME_PREFIX | grep Target | cut -f3 -d ' ' | sudo xargs -n1 tgt-admin --delete || true
             # Clean out existing volumes
@@ -129,6 +173,9 @@
 function start_cinder() {
     if is_service_enabled c-vol; then
         if [[ "$os_PACKAGE" = "deb" ]]; then
+            if [[ ! -f /etc/tgt/conf.d/cinder.conf ]]; then
+               echo "include $CINDER_DIR/volumes/*" | sudo tee /etc/tgt/conf.d/cinder.conf
+            fi
             # tgt in oneiric doesn't restart properly if tgtd isn't running
             # do it in two steps
             sudo stop tgt || true
diff --git a/openrc b/openrc
index be7850b..4430e82 100644
--- a/openrc
+++ b/openrc
@@ -20,6 +20,9 @@
 # Find the other rc files
 RC_DIR=$(cd $(dirname "$BASH_SOURCE") && pwd)
 
+# Import common functions
+source $RC_DIR/functions
+
 # Load local configuration
 source $RC_DIR/stackrc
 
diff --git a/samples/local.sh b/samples/local.sh
index 83637f9..2c54b10 100755
--- a/samples/local.sh
+++ b/samples/local.sh
@@ -13,6 +13,9 @@
 # Keep track of the devstack directory
 TOP_DIR=$(cd $(dirname "$0") && pwd)
 
+# Import common functions
+source $TOP_DIR/functions
+
 # Use openrc + stackrc + localrc for settings
 source $TOP_DIR/stackrc
 
diff --git a/stack.sh b/stack.sh
index e013476..ae06629 100755
--- a/stack.sh
+++ b/stack.sh
@@ -26,19 +26,8 @@
 
 # Determine what system we are running on.  This provides ``os_VENDOR``,
 # ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME``
-GetOSVersion
-
-# Translate the OS version values into common nomenclature
-if [[ "$os_VENDOR" =~ (Ubuntu) ]]; then
-    # 'Everyone' refers to Ubuntu releases by the code name adjective
-    DISTRO=$os_CODENAME
-elif [[ "$os_VENDOR" =~ (Fedora) ]]; then
-    # For Fedora, just use 'f' and the release
-    DISTRO="f$os_RELEASE"
-else
-    # Catch-all for now is Vendor + Release + Update
-    DISTRO="$os_VENDOR-$os_RELEASE.$os_UPDATE"
-fi
+# and ``DISTRO``
+GetDistro
 
 
 # Settings
@@ -89,20 +78,15 @@
 # Sanity Check
 # ============
 
-# We are looking for services with a - at the beginning to force
-# excluding those services. For example if you want to install all the default
-# services but not nova-volume (n-vol) you can have this set in your localrc :
-# ENABLED_SERVICES+=",-n-vol"
-for service in ${ENABLED_SERVICES//,/ }; do
-    if [[ ${service} == -* ]]; then
-        ENABLED_SERVICES=$(echo ${ENABLED_SERVICES}|sed -r "s/(,)?(-)?${service#-}(,)?/,/g")
-    fi
-done
+# Remove services which were negated in ENABLED_SERVICES
+# using the "-" prefix (e.g., "-n-vol") instead of
+# calling disable_service().
+disable_negated_services
 
 # 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} =~ (oneiric|precise|quantal|f16) ]]; then
-    echo "WARNING: this script has been tested on oneiric, precise and f16"
+if [[ ! ${DISTRO} =~ (oneiric|precise|quantal|f16|f17) ]]; then
+    echo "WARNING: this script has not been tested on $DISTRO"
     if [[ "$FORCE" != "yes" ]]; then
         echo "If you wish to run this script anyway run with FORCE=yes"
         exit 1
@@ -213,6 +197,9 @@
     # Set up devstack sudoers
     TEMPFILE=`mktemp`
     echo "`whoami` ALL=(root) NOPASSWD:ALL" >$TEMPFILE
+    # Some binaries might be under /sbin or /usr/sbin, so make sure sudo will
+    # see them by forcing PATH
+    echo "Defaults:`whoami` secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE
     chmod 0440 $TEMPFILE
     sudo chown root:root $TEMPFILE
     sudo mv $TEMPFILE /etc/sudoers.d/50_stack_sh
@@ -249,7 +236,6 @@
 # Get project function libraries
 source $TOP_DIR/lib/cinder
 
-
 # Set the destination directories for openstack projects
 NOVA_DIR=$DEST/nova
 HORIZON_DIR=$DEST/horizon
@@ -274,6 +260,13 @@
 Q_PORT=${Q_PORT:-9696}
 # Default Quantum Host
 Q_HOST=${Q_HOST:-localhost}
+# Which Quantum API nova should use
+NOVA_USE_QUANTUM_API=${NOVA_USE_QUANTUM_API:-v1}
+# Default admin username
+Q_ADMIN_USERNAME=${Q_ADMIN_USERNAME:-quantum}
+# Default auth strategy
+Q_AUTH_STRATEGY=${Q_AUTH_STRATEGY:-keystone}
+
 
 # Default Melange Port
 M_PORT=${M_PORT:-9898}
@@ -385,6 +378,7 @@
 PUBLIC_INTERFACE=${PUBLIC_INTERFACE:-br100}
 FIXED_RANGE=${FIXED_RANGE:-10.0.0.0/24}
 FIXED_NETWORK_SIZE=${FIXED_NETWORK_SIZE:-256}
+NETWORK_GATEWAY=${NETWORK_GATEWAY:-10.0.0.1}
 FLOATING_RANGE=${FLOATING_RANGE:-172.24.4.224/28}
 NET_MAN=${NET_MAN:-FlatDHCPManager}
 EC2_DMZ_HOST=${EC2_DMZ_HOST:-$SERVICE_HOST}
@@ -467,9 +461,9 @@
 GLANCE_HOSTPORT=${GLANCE_HOSTPORT:-$SERVICE_HOST:9292}
 
 
-# SWIFT
+# Swift
 # -----
-# TODO: implement glance support
+
 # TODO: add logging to different location.
 
 # By default the location of swift drives and objects is located inside
@@ -481,7 +475,7 @@
 # directory, change SWIFT_CONFIG_DIR if you want to adjust that.
 SWIFT_CONFIG_DIR=${SWIFT_CONFIG_DIR:-/etc/swift}
 
-# devstack will create a loop-back disk formatted as XFS to store the
+# DevStack will create a loop-back disk formatted as XFS to store the
 # swift data. By default the disk size is 1 gigabyte. The variable
 # SWIFT_LOOPBACK_DISK_SIZE specified in bytes allow you to change
 # that.
@@ -504,9 +498,11 @@
 SWIFT_REPLICAS=${SWIFT_REPLICAS:-3}
 
 if is_service_enabled swift; then
-    # If we are using swift, we can default the s3 port to swift instead
+    # If we are using swift3, we can default the s3 port to swift instead
     # of nova-objectstore
-    S3_SERVICE_PORT=${S3_SERVICE_PORT:-8080}
+    if is_service_enabled swift3;then
+        S3_SERVICE_PORT=${S3_SERVICE_PORT:-8080}
+    fi
     # We only ask for Swift Hash if we have enabled swift service.
     # SWIFT_HASH is a random unique string for a swift cluster that
     # can never change.
@@ -516,6 +512,7 @@
 # Set default port for nova-objectstore
 S3_SERVICE_PORT=${S3_SERVICE_PORT:-3333}
 
+
 # Keystone
 # --------
 
@@ -613,10 +610,10 @@
 
 # Install Packages
 # ================
-#
+
 # Openstack uses a fair number of other projects.
 
-# install package requirements
+# Install package requirements
 if [[ "$os_PACKAGE" = "deb" ]]; then
     apt_get update
     install_package $(get_packages $FILES/apts)
@@ -624,12 +621,137 @@
     install_package $(get_packages $FILES/rpms)
 fi
 
-# install python requirements
+if [[ $SYSLOG != "False" ]]; then
+    install_package rsyslog-relp
+fi
+
+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"
+elif is_service_enabled qpid; then
+    if [[ "$os_PACKAGE" = "rpm" ]]; then
+        install_package qpid-cpp-server
+    else
+        install_package qpidd
+    fi
+fi
+
+if is_service_enabled mysql; then
+
+    if [[ "$os_PACKAGE" = "deb" ]]; then
+        # Seed configuration with mysql password so that apt-get install doesn't
+        # prompt us for a password upon install.
+        cat <<MYSQL_PRESEED | sudo debconf-set-selections
+mysql-server-5.1 mysql-server/root_password password $MYSQL_PASSWORD
+mysql-server-5.1 mysql-server/root_password_again password $MYSQL_PASSWORD
+mysql-server-5.1 mysql-server/start_on_boot boolean true
+MYSQL_PRESEED
+    fi
+
+    # while ``.my.cnf`` is not needed for openstack to function, it is useful
+    # as it allows you to access the mysql databases via ``mysql nova`` instead
+    # of having to specify the username/password each time.
+    if [[ ! -e $HOME/.my.cnf ]]; then
+        cat <<EOF >$HOME/.my.cnf
+[client]
+user=$MYSQL_USER
+password=$MYSQL_PASSWORD
+host=$MYSQL_HOST
+EOF
+        chmod 0600 $HOME/.my.cnf
+    fi
+    # Install mysql-server
+    install_package mysql-server
+fi
+
+if is_service_enabled quantum; then
+    if [[ "$Q_PLUGIN" = "linuxbridge" ]]; then
+        # Install deps
+        # FIXME add to files/apts/quantum, but don't install if not needed!
+        install_package python-configobj
+    fi
+fi
+
+if is_service_enabled horizon; then
+    if [[ "$os_PACKAGE" = "deb" ]]; then
+        # Install apache2, which is NOPRIME'd
+        install_package apache2 libapache2-mod-wsgi
+    else
+        sudo rm -f /etc/httpd/conf.d/000-*
+        install_package httpd mod_wsgi
+    fi
+fi
+
+if is_service_enabled q-agt; then
+    if [[ "$Q_PLUGIN" = "openvswitch" ]]; then
+        # Install deps
+        # FIXME add to files/apts/quantum, but don't install if not needed!
+        if [[ "$os_PACKAGE" = "deb" ]]; then
+            kernel_version=`cat /proc/version | cut -d " " -f3`
+            install_package make fakeroot dkms openvswitch-switch openvswitch-datapath-dkms linux-headers-$kernel_version
+        else
+            ### FIXME(dtroyer): Find RPMs for OpenVSwitch
+            echo "OpenVSwitch packages need to be located"
+        fi
+    elif [[ "$Q_PLUGIN" = "linuxbridge" ]]; then
+       install_package bridge-utils
+    fi
+fi
+
+if is_service_enabled n-cpu; then
+
+    # Virtualization Configuration
+    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+    if [[ "$os_PACKAGE" = "deb" ]]; then
+        LIBVIRT_PKG_NAME=libvirt-bin
+    else
+        LIBVIRT_PKG_NAME=libvirt
+    fi
+    install_package $LIBVIRT_PKG_NAME
+    # Install and configure **LXC** if specified.  LXC is another approach to
+    # splitting a system into many smaller parts.  LXC uses cgroups and chroot
+    # to simulate multiple systems.
+    if [[ "$LIBVIRT_TYPE" == "lxc" ]]; then
+        if [[ "$os_PACKAGE" = "deb" ]]; then
+            if [[ "$DISTRO" > natty ]]; then
+                install_package cgroup-lite
+            fi
+        else
+            ### FIXME(dtroyer): figure this out
+            echo "RPM-based cgroup not implemented yet"
+            yum_install libcgroup-tools
+        fi
+    fi
+fi
+
+if is_service_enabled swift; then
+    # Install memcached for swift.
+    install_package memcached
+fi
+
+TRACK_DEPENDS=${TRACK_DEPENDS:-False}
+
+# Install python packages into a virtualenv so that we can track them
+if [[ $TRACK_DEPENDS = True ]] ; then
+    install_package python-virtualenv
+
+    rm -rf $DEST/.venv
+    virtualenv --system-site-packages $DEST/.venv
+    source $DEST/.venv/bin/activate
+    $DEST/.venv/bin/pip freeze > $DEST/requires-pre-pip
+fi
+
+# Install python requirements
 pip_install $(get_packages $FILES/pips | sort -u)
 
-# compute service
+# Check out OpenStack sources
 git_clone $NOVA_REPO $NOVA_DIR $NOVA_BRANCH
-# python client library to nova that horizon (and others) use
+
+# Check out the client libs that are used most
 git_clone $KEYSTONECLIENT_REPO $KEYSTONECLIENT_DIR $KEYSTONECLIENT_BRANCH
 git_clone $NOVACLIENT_REPO $NOVACLIENT_DIR $NOVACLIENT_BRANCH
 git_clone $OPENSTACKCLIENT_REPO $OPENSTACKCLIENT_DIR $OPENSTACKCLIENT_BRANCH
@@ -645,8 +767,10 @@
     git_clone $SWIFT_REPO $SWIFT_DIR $SWIFT_BRANCH
     # storage service client and and Library
     git_clone $SWIFTCLIENT_REPO $SWIFTCLIENT_DIR $SWIFTCLIENT_BRANCH
-    # swift3 middleware to provide S3 emulation to Swift
-    git_clone $SWIFT3_REPO $SWIFT3_DIR $SWIFT3_BRANCH
+    if is_service_enabled swift3; then
+        # swift3 middleware to provide S3 emulation to Swift
+        git_clone $SWIFT3_REPO $SWIFT3_DIR $SWIFT3_BRANCH
+    fi
 fi
 if is_service_enabled g-api n-api; then
     # image catalog service
@@ -678,11 +802,10 @@
     install_cinder
 fi
 
-
 # Initialization
 # ==============
 
-# setup our checkouts so they are installed into python path
+# Set up our checkouts so they are installed into python path
 # allowing ``import nova`` or ``import glance.client``
 setup_develop $KEYSTONECLIENT_DIR
 setup_develop $NOVACLIENT_DIR
@@ -693,6 +816,8 @@
 if is_service_enabled swift; then
     setup_develop $SWIFT_DIR
     setup_develop $SWIFTCLIENT_DIR
+fi
+if is_service_enabled swift3; then
     setup_develop $SWIFT3_DIR
 fi
 if is_service_enabled g-api n-api; then
@@ -720,12 +845,19 @@
     configure_cinder
 fi
 
+if [[ $TRACK_DEPENDS = True ]] ; then
+    $DEST/.venv/bin/pip freeze > $DEST/requires-post-pip
+    if ! diff -Nru $DEST/requires-pre-pip $DEST/requires-post-pip > $DEST/requires.diff ; then
+        cat $DEST/requires.diff
+    fi
+    echo "Ran stack.sh in depend tracking mode, bailing out now"
+    exit 0
+fi
 
 # Syslog
 # ------
 
 if [[ $SYSLOG != "False" ]]; then
-    install_package rsyslog-relp
     if [[ "$SYSLOG_HOST" = "$HOST_IP" ]]; then
         # Configure the master host to receive
         cat <<EOF >/tmp/90-stack-m.conf
@@ -748,12 +880,7 @@
 # --------------
 
 if is_service_enabled rabbit; then
-    # Install and start 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"
+    # Start rabbitmq-server
     if [[ "$os_PACKAGE" = "rpm" ]]; then
         # RPM doesn't start the service
         restart_service rabbitmq-server
@@ -761,45 +888,17 @@
     # change the rabbit password since the default is "guest"
     sudo rabbitmqctl change_password guest $RABBIT_PASSWORD
 elif is_service_enabled qpid; then
-    if [[ "$os_PACKAGE" = "rpm" ]]; then
-        install_package qpid-cpp-server
-        restart_service qpidd
-    else
-        install_package qpidd
-    fi
+    restart_service qpidd
 fi
 
 
 # Mysql
 # -----
 
+
 if is_service_enabled mysql; then
 
-    if [[ "$os_PACKAGE" = "deb" ]]; then
-        # Seed configuration with mysql password so that apt-get install doesn't
-        # prompt us for a password upon install.
-        cat <<MYSQL_PRESEED | sudo debconf-set-selections
-mysql-server-5.1 mysql-server/root_password password $MYSQL_PASSWORD
-mysql-server-5.1 mysql-server/root_password_again password $MYSQL_PASSWORD
-mysql-server-5.1 mysql-server/start_on_boot boolean true
-MYSQL_PRESEED
-    fi
-
-    # while ``.my.cnf`` is not needed for openstack to function, it is useful
-    # as it allows you to access the mysql databases via ``mysql nova`` instead
-    # of having to specify the username/password each time.
-    if [[ ! -e $HOME/.my.cnf ]]; then
-        cat <<EOF >$HOME/.my.cnf
-[client]
-user=$MYSQL_USER
-password=$MYSQL_PASSWORD
-host=$MYSQL_HOST
-EOF
-        chmod 0600 $HOME/.my.cnf
-    fi
-
-    # Install and start mysql-server
-    install_package mysql-server
+    #start mysql-server
     if [[ "$os_PACKAGE" = "rpm" ]]; then
         # RPM doesn't start the service
         start_service mysqld
@@ -878,16 +977,17 @@
     fi
 }
 
-# create a new named screen to run processes in
+# Create a new named screen to run processes in
 screen -d -m -S stack -t stack -s /bin/bash
 sleep 1
-# set a reasonable statusbar
+# Set a reasonable statusbar
 screen -r stack -X hardstatus alwayslastline "$SCREEN_HARDSTATUS"
 
+
 # Horizon
 # -------
 
-# Setup the django horizon application to serve via apache/wsgi
+# Set up the django horizon application to serve via apache/wsgi
 
 if is_service_enabled horizon; then
 
@@ -901,17 +1001,15 @@
     # Initialize the horizon database (it stores sessions and notices shown to
     # users).  The user system is external (keystone).
     cd $HORIZON_DIR
-    python manage.py syncdb
+    python manage.py syncdb --noinput
     cd $TOP_DIR
 
-    # create an empty directory that apache uses as docroot
+    # Create an empty directory that apache uses as docroot
     sudo mkdir -p $HORIZON_DIR/.blackhole
 
     if [[ "$os_PACKAGE" = "deb" ]]; then
-        # Install apache2, which is NOPRIME'd
         APACHE_NAME=apache2
         APACHE_CONF=sites-available/horizon
-        install_package apache2 libapache2-mod-wsgi
         # Clean up the old config name
         sudo rm -f /etc/apache2/sites-enabled/000-default
         # Be a good citizen and use the distro tools here
@@ -921,8 +1019,6 @@
         # Install httpd, which is NOPRIME'd
         APACHE_NAME=httpd
         APACHE_CONF=conf.d/horizon.conf
-        sudo rm -f /etc/httpd/conf.d/000-*
-        install_package httpd mod_wsgi
         sudo sed '/^Listen/s/^.*$/Listen 0.0.0.0:80/' -i /etc/httpd/conf/httpd.conf
     fi
     ## Configure apache to run horizon
@@ -1011,8 +1107,10 @@
 
 fi
 
-# Quantum (for controller or agent nodes)
+
+# Quantum
 # -------
+
 if is_service_enabled quantum; then
     # Put config files in /etc/quantum for everyone to find
     if [[ ! -d /etc/quantum ]]; then
@@ -1024,26 +1122,30 @@
         Q_PLUGIN_CONF_PATH=etc/quantum/plugins/openvswitch
         Q_PLUGIN_CONF_FILENAME=ovs_quantum_plugin.ini
         Q_DB_NAME="ovs_quantum"
-        Q_PLUGIN_CLASS="quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPlugin"
+        if [[ "$NOVA_USE_QUANTUM_API" = "v1" ]]; then
+            Q_PLUGIN_CLASS="quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPlugin"
+        elif [[ "$NOVA_USE_QUANTUM_API" = "v2" ]]; then
+            Q_PLUGIN_CLASS="quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2"
+        fi
     elif [[ "$Q_PLUGIN" = "linuxbridge" ]]; then
-        # Install deps
-        # FIXME add to files/apts/quantum, but don't install if not needed!
-        install_package python-configobj
         Q_PLUGIN_CONF_PATH=etc/quantum/plugins/linuxbridge
         Q_PLUGIN_CONF_FILENAME=linuxbridge_conf.ini
         Q_DB_NAME="quantum_linux_bridge"
-        Q_PLUGIN_CLASS="quantum.plugins.linuxbridge.LinuxBridgePlugin.LinuxBridgePlugin"
+        if [[ "$NOVA_USE_QUANTUM_API" = "v1" ]]; then
+            Q_PLUGIN_CLASS="quantum.plugins.linuxbridge.LinuxBridgePlugin.LinuxBridgePlugin"
+        elif [[ "$NOVA_USE_QUANTUM_API" = "v2" ]]; then
+            Q_PLUGIN_CLASS="quantum.plugins.linuxbridge.lb_quantum_plugin.LinuxBridgePluginV2"
+        fi
     else
         echo "Unknown Quantum plugin '$Q_PLUGIN'.. exiting"
         exit 1
     fi
 
-    # if needed, move config file from $QUANTUM_DIR/etc/quantum to /etc/quantum
+    # If needed, move config file from $QUANTUM_DIR/etc/quantum to /etc/quantum
     mkdir -p /$Q_PLUGIN_CONF_PATH
     Q_PLUGIN_CONF_FILE=$Q_PLUGIN_CONF_PATH/$Q_PLUGIN_CONF_FILENAME
-    if [[ -e $QUANTUM_DIR/$Q_PLUGIN_CONF_FILE ]]; then
-            sudo mv $QUANTUM_DIR/$Q_PLUGIN_CONF_FILE /$Q_PLUGIN_CONF_FILE
-    fi
+    cp $QUANTUM_DIR/$Q_PLUGIN_CONF_FILE /$Q_PLUGIN_CONF_FILE
+
     sudo sed -i -e "s/^sql_connection =.*$/sql_connection = mysql:\/\/$MYSQL_USER:$MYSQL_PASSWORD@$MYSQL_HOST\/$Q_DB_NAME?charset=utf8/g" /$Q_PLUGIN_CONF_FILE
 
     OVS_ENABLE_TUNNELING=${OVS_ENABLE_TUNNELING:-True}
@@ -1056,6 +1158,12 @@
         fi
         sudo sed -i -e "s/.*enable_tunneling = .*$/enable_tunneling = $OVS_ENABLE_TUNNELING/g" /$Q_PLUGIN_CONF_FILE
     fi
+
+    if [[ "$NOVA_USE_QUANTUM_API" = "v1" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE AGENT target_v2_api False
+    elif [[ "$NOVA_USE_QUANTUM_API" = "v2" ]]; then
+        iniset /$Q_PLUGIN_CONF_FILE AGENT target_v2_api True
+    fi
 fi
 
 # Quantum service (for controller node)
@@ -1064,17 +1172,9 @@
     Q_API_PASTE_FILE=/etc/quantum/api-paste.ini
     Q_POLICY_FILE=/etc/quantum/policy.json
 
-    if [[ -e $QUANTUM_DIR/etc/quantum.conf ]]; then
-      sudo mv $QUANTUM_DIR/etc/quantum.conf $Q_CONF_FILE
-    fi
-
-    if [[ -e $QUANTUM_DIR/etc/api-paste.ini ]]; then
-      sudo mv $QUANTUM_DIR/etc/api-paste.ini $Q_API_PASTE_FILE
-    fi
-
-    if [[ -e $QUANTUM_DIR/etc/policy.json ]]; then
-      sudo mv $QUANTUM_DIR/etc/policy.json $Q_POLICY_FILE
-    fi
+    cp $QUANTUM_DIR/etc/quantum.conf $Q_CONF_FILE
+    cp $QUANTUM_DIR/etc/api-paste.ini $Q_API_PASTE_FILE
+    cp $QUANTUM_DIR/etc/policy.json $Q_POLICY_FILE
 
     if is_service_enabled mysql; then
             mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e "DROP DATABASE IF EXISTS $Q_DB_NAME;"
@@ -1085,22 +1185,22 @@
     fi
 
     # Update either configuration file with plugin
-    sudo sed -i -e "s/^core_plugin =.*$/core_plugin = $Q_PLUGIN_CLASS/g" $Q_CONF_FILE
-    screen_it q-svc "cd $QUANTUM_DIR && python $QUANTUM_DIR/bin/quantum-server --config-file $Q_CONF_FILE"
+    iniset $Q_CONF_FILE DEFAULT core_plugin $Q_PLUGIN_CLASS
+
+    iniset $Q_CONF_FILE DEFAULT auth_strategy $Q_AUTH_STRATEGY
+    iniset $Q_API_PASTE_FILE filter:authtoken auth_host $KEYSTONE_SERVICE_HOST
+    iniset $Q_API_PASTE_FILE filter:authtoken auth_port $KEYSTONE_AUTH_PORT
+    iniset $Q_API_PASTE_FILE filter:authtoken auth_protocol $KEYSTONE_SERVICE_PROTOCOL
+    iniset $Q_API_PASTE_FILE filter:authtoken admin_tenant_name $SERVICE_TENANT_NAME
+    iniset $Q_API_PASTE_FILE filter:authtoken admin_user $Q_ADMIN_USERNAME
+    iniset $Q_API_PASTE_FILE filter:authtoken admin_password $SERVICE_PASSWORD
+
+    screen_it q-svc "cd $QUANTUM_DIR && python $QUANTUM_DIR/bin/quantum-server --config-file $Q_CONF_FILE --config-file /$Q_PLUGIN_CONF_FILE"
 fi
 
 # Quantum agent (for compute nodes)
 if is_service_enabled q-agt; then
     if [[ "$Q_PLUGIN" = "openvswitch" ]]; then
-        # Install deps
-        # FIXME add to files/apts/quantum, but don't install if not needed!
-        if [[ "$os_PACKAGE" = "deb" ]]; then
-            kernel_version=`cat /proc/version | cut -d " " -f3`
-            install_package make fakeroot dkms openvswitch-switch openvswitch-datapath-dkms linux-headers-$kernel_version
-        else
-            ### FIXME(dtroyer): Find RPMs for OpenVSwitch
-            echo "OpenVSwitch packages need to be located"
-        fi
         # Set up integration bridge
         OVS_BRIDGE=${OVS_BRIDGE:-br-int}
         for PORT in `sudo ovs-vsctl --no-wait list-ports $OVS_BRIDGE`; do
@@ -1111,17 +1211,47 @@
         sudo ovs-vsctl --no-wait add-br $OVS_BRIDGE
         sudo ovs-vsctl --no-wait br-set-external-id $OVS_BRIDGE bridge-id br-int
         sudo sed -i -e "s/.*local_ip = .*/local_ip = $HOST_IP/g" /$Q_PLUGIN_CONF_FILE
-        AGENT_BINARY=$QUANTUM_DIR/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py
+        AGENT_BINARY="$QUANTUM_DIR/quantum/plugins/openvswitch/agent/ovs_quantum_agent.py"
     elif [[ "$Q_PLUGIN" = "linuxbridge" ]]; then
        # Start up the quantum <-> linuxbridge agent
-       install_package bridge-utils
-        #set the default network interface
+       # set the default network interface
        QUANTUM_LB_PRIVATE_INTERFACE=${QUANTUM_LB_PRIVATE_INTERFACE:-$GUEST_INTERFACE_DEFAULT}
        sudo sed -i -e "s/^physical_interface = .*$/physical_interface = $QUANTUM_LB_PRIVATE_INTERFACE/g" /$Q_PLUGIN_CONF_FILE
-       AGENT_BINARY=$QUANTUM_DIR/quantum/plugins/linuxbridge/agent/linuxbridge_quantum_agent.py
+       AGENT_BINARY="$QUANTUM_DIR/quantum/plugins/linuxbridge/agent/linuxbridge_quantum_agent.py"
     fi
     # Start up the quantum agent
-    screen_it q-agt "sudo python $AGENT_BINARY /$Q_PLUGIN_CONF_FILE -v"
+    screen_it q-agt "sudo python $AGENT_BINARY --config-file $Q_CONF_FILE --config-file /$Q_PLUGIN_CONF_FILE"
+fi
+
+# Quantum DHCP
+if is_service_enabled q-dhcp; then
+    AGENT_DHCP_BINARY="$QUANTUM_DIR/bin/quantum-dhcp-agent"
+
+    Q_DHCP_CONF_FILE=/etc/quantum/dhcp_agent.ini
+
+    if [[ -e $QUANTUM_DIR/etc/dhcp_agent.ini ]]; then
+      sudo cp $QUANTUM_DIR/etc/dhcp_agent.ini $Q_DHCP_CONF_FILE
+    fi
+
+    # Set verbose
+    iniset $Q_DHCP_CONF_FILE DEFAULT verbose True
+    # Set debug
+    iniset $Q_DHCP_CONF_FILE DEFAULT debug True
+
+    # Update database
+    iniset $Q_DHCP_CONF_FILE DEFAULT db_connection "mysql:\/\/$MYSQL_USER:$MYSQL_PASSWORD@$MYSQL_HOST\/$Q_DB_NAME?charset=utf8"
+    iniset $Q_DHCP_CONF_FILE DEFAULT auth_url "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT/v2.0"
+    iniset $Q_DHCP_CONF_FILE DEFAULT admin_tenant_name $SERVICE_TENANT_NAME
+    iniset $Q_DHCP_CONF_FILE DEFAULT admin_user $Q_ADMIN_USERNAME
+    iniset $Q_DHCP_CONF_FILE DEFAULT admin_password $SERVICE_PASSWORD
+
+    if [[ "$Q_PLUGIN" = "openvswitch" ]]; then
+        iniset $Q_DHCP_CONF_FILE DEFAULT interface_driver quantum.agent.linux.interface.OVSInterfaceDriver
+    elif [[ "$Q_PLUGIN" = "linuxbridge" ]]; then
+        iniset $Q_DHCP_CONF_FILE DEFAULT interface_driver quantum.agent.linux.interface.BridgeInterfaceDriver
+    fi
+    # Start up the quantum agent
+    screen_it q-dhcp "sudo python $AGENT_DHCP_BINARY --config-file=$Q_DHCP_CONF_FILE"
 fi
 
 # Melange service
@@ -1147,7 +1277,6 @@
 fi
 
 
-
 # Nova
 # ----
 
@@ -1183,7 +1312,7 @@
     ROOTWRAP_SUDOER_CMD="$NOVA_ROOTWRAP *"
 fi
 
-# Set up the rootwrap sudoers
+# Set up the rootwrap sudoers for nova
 TEMPFILE=`mktemp`
 echo "$USER ALL=(root) NOPASSWD: $ROOTWRAP_SUDOER_CMD" >$TEMPFILE
 chmod 0440 $TEMPFILE
@@ -1231,15 +1360,6 @@
 
 if is_service_enabled n-cpu; then
 
-    # Virtualization Configuration
-    # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-    if [[ "$os_PACKAGE" = "deb" ]]; then
-        LIBVIRT_PKG_NAME=libvirt-bin
-    else
-        LIBVIRT_PKG_NAME=libvirt
-    fi
-    install_package $LIBVIRT_PKG_NAME
-
     # Force IP forwarding on, just on case
     sudo sysctl -w net.ipv4.ip_forward=1
 
@@ -1262,9 +1382,7 @@
     # to simulate multiple systems.
     if [[ "$LIBVIRT_TYPE" == "lxc" ]]; then
         if [[ "$os_PACKAGE" = "deb" ]]; then
-            if [[ "$DISTRO" > natty ]]; then
-                install_package cgroup-lite
-            else
+            if [[ ! "$DISTRO" > natty ]]; then
                 cgline="none /cgroup cgroup cpuacct,memory,devices,cpu,freezer,blkio 0 0"
                 sudo mkdir -p /cgroup
                 if ! grep -q cgroup /etc/fstab; then
@@ -1274,16 +1392,12 @@
                     sudo mount /cgroup
                 fi
             fi
-        else
-            ### FIXME(dtroyer): figure this out
-            echo "RPM-based cgroup not implemented yet"
-            yum_install libcgroup-tools
         fi
     fi
 
     QEMU_CONF=/etc/libvirt/qemu.conf
     if is_service_enabled quantum && [[ $Q_PLUGIN = "openvswitch" ]] && ! sudo grep -q '^cgroup_device_acl' $QEMU_CONF ; then
-        # add /dev/net/tun to cgroup_device_acls, needed for type=ethernet interfaces
+        # Add /dev/net/tun to cgroup_device_acls, needed for type=ethernet interfaces
         sudo chmod 666 $QEMU_CONF
         sudo cat <<EOF >> /etc/libvirt/qemu.conf
 cgroup_device_acl = [
@@ -1367,13 +1481,14 @@
     sudo sysctl -w net.ipv4.ip_forward=1
 fi
 
+
 # Storage Service
+# ---------------
+
 if is_service_enabled swift; then
-    # Install memcached for swift.
-    install_package memcached
 
     # We make sure to kill all swift processes first
-    pkill -f -9 swift-
+    swift-init all stop || true
 
     # We first do a bit of setup by creating the directories and
     # changing the permissions so we can run it as our user.
@@ -1447,11 +1562,15 @@
         sudo sed -i '/disable *= *yes/ { s/yes/no/ }' /etc/xinetd.d/rsync
     fi
 
+    if is_service_enabled swift3;then
+        swift_auth_server="s3token "
+    fi
+
     # By default Swift will be installed with the tempauth middleware
     # which has some default username and password if you have
     # configured keystone it will checkout the directory.
     if is_service_enabled key; then
-        swift_auth_server="s3token authtoken keystone"
+        swift_auth_server+="authtoken keystone"
     else
         swift_auth_server=tempauth
     fi
@@ -1474,7 +1593,10 @@
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port
     iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port ${SWIFT_DEFAULT_BIND_PORT:-8080}
 
-    iniset ${SWIFT_CONFIG_PROXY_SERVER} pipeline:main pipeline "catch_errors healthcheck cache ratelimit swift3 ${swift_auth_server} proxy-logging proxy-server"
+    # Only enable Swift3 if we have it enabled in ENABLED_SERVICES
+    is_service_enabled swift3 && swift3=swift3 || swift3=""
+
+    iniset ${SWIFT_CONFIG_PROXY_SERVER} pipeline:main pipeline "catch_errors healthcheck cache ratelimit ${swift3} ${swift_auth_server} proxy-logging proxy-server"
 
     iniset ${SWIFT_CONFIG_PROXY_SERVER} app:proxy-server account_autocreate true
 
@@ -1484,16 +1606,6 @@
 paste.filter_factory = keystone.middleware.swift_auth:filter_factory
 operator_roles = Member,admin
 
-# NOTE(chmou): s3token middleware is not updated yet to use only
-# username and password.
-[filter:s3token]
-paste.filter_factory = keystone.middleware.s3_token:filter_factory
-auth_port = ${KEYSTONE_AUTH_PORT}
-auth_host = ${KEYSTONE_AUTH_HOST}
-auth_protocol = ${KEYSTONE_AUTH_PROTOCOL}
-auth_token = ${SERVICE_TOKEN}
-admin_token = ${SERVICE_TOKEN}
-
 [filter:authtoken]
 paste.filter_factory = keystone.middleware.auth_token:filter_factory
 auth_host = ${KEYSTONE_AUTH_HOST}
@@ -1503,10 +1615,24 @@
 admin_tenant_name = ${SERVICE_TENANT_NAME}
 admin_user = swift
 admin_password = ${SERVICE_PASSWORD}
+delay_auth_decision = 1
+EOF
+    if is_service_enabled swift3;then
+        cat <<EOF>>${SWIFT_CONFIG_PROXY_SERVER}
+# NOTE(chmou): s3token middleware is not updated yet to use only
+# username and password.
+[filter:s3token]
+paste.filter_factory = keystone.middleware.s3_token:filter_factory
+auth_port = ${KEYSTONE_AUTH_PORT}
+auth_host = ${KEYSTONE_AUTH_HOST}
+auth_protocol = ${KEYSTONE_AUTH_PROTOCOL}
+auth_token = ${SERVICE_TOKEN}
+admin_token = ${SERVICE_TOKEN}
 
 [filter:swift3]
 use = egg:swift3#swift3
 EOF
+    fi
 
     cp ${SWIFT_DIR}/etc/swift.conf-sample ${SWIFT_CONFIG_DIR}/swift.conf
     iniset ${SWIFT_CONFIG_DIR}/swift.conf swift-hash swift_hash_path_suffix ${SWIFT_HASH}
@@ -1627,11 +1753,10 @@
     # volume group, create your own volume group called ``stack-volumes`` before
     # invoking ``stack.sh``.
     #
-    # By default, the backing file is 2G in size, and is stored in ``/opt/stack/data``.
+    # By default, the backing file is 5G in size, and is stored in ``/opt/stack/data``.
 
     if ! sudo vgs $VOLUME_GROUP; then
         VOLUME_BACKING_FILE=${VOLUME_BACKING_FILE:-$DATA_DIR/${VOLUME_GROUP}-backing-file}
-        VOLUME_BACKING_FILE_SIZE=${VOLUME_BACKING_FILE_SIZE:-2052M}
         # Only create if the file doesn't already exists
         [[ -f $VOLUME_BACKING_FILE ]] || truncate -s $VOLUME_BACKING_FILE_SIZE $VOLUME_BACKING_FILE
         DEV=`sudo losetup -f --show $VOLUME_BACKING_FILE`
@@ -1640,6 +1765,14 @@
     fi
 
     if sudo vgs $VOLUME_GROUP; then
+        if [[ "$os_PACKAGE" = "rpm" ]]; then
+            # RPM doesn't start the service
+            start_service tgtd
+        fi
+
+        # Setup tgtd configuration files
+        mkdir -p $NOVA_DIR/volumes
+
         # Remove nova iscsi targets
         sudo tgtadm --op show --mode target | grep $VOLUME_NAME_PREFIX | grep Target | cut -f3 -d ' ' | sudo xargs -n1 tgt-admin --delete || true
         # Clean out existing volumes
@@ -1652,13 +1785,18 @@
     fi
 
     if [[ "$os_PACKAGE" = "deb" ]]; then
+
+        # Setup the tgt configuration file
+        if [[ ! -f /etc/tgt/conf.d/nova.conf ]]; then
+           echo "include $NOVA_DIR/volumes/*" | sudo tee /etc/tgt/conf.d/nova.conf
+        fi
+
         # tgt in oneiric doesn't restart properly if tgtd isn't running
         # do it in two steps
         sudo stop tgt || true
         sudo start tgt
     else
-        # bypass redirection to systemctl during restart
-        sudo /sbin/service --skip-redirect tgtd restart
+        restart_service tgtd
     fi
 fi
 
@@ -1667,7 +1805,7 @@
     echo "$1" >> $NOVA_CONF_DIR/$NOVA_CONF
 }
 
-# remove legacy nova.conf
+# Remove legacy nova.conf
 rm -f $NOVA_DIR/bin/nova.conf
 
 # (re)create nova.conf
@@ -1683,15 +1821,27 @@
 add_nova_opt "s3_host=$SERVICE_HOST"
 add_nova_opt "s3_port=$S3_SERVICE_PORT"
 if is_service_enabled quantum; then
-    add_nova_opt "network_manager=nova.network.quantum.manager.QuantumManager"
-    add_nova_opt "quantum_connection_host=$Q_HOST"
-    add_nova_opt "quantum_connection_port=$Q_PORT"
+    if [[ "$NOVA_USE_QUANTUM_API" = "v1" ]]; then
+        add_nova_opt "network_manager=nova.network.quantum.manager.QuantumManager"
+        add_nova_opt "quantum_connection_host=$Q_HOST"
+        add_nova_opt "quantum_connection_port=$Q_PORT"
+        add_nova_opt "quantum_use_dhcp=True"
 
-    if is_service_enabled melange; then
-        add_nova_opt "quantum_ipam_lib=nova.network.quantum.melange_ipam_lib"
-        add_nova_opt "use_melange_mac_generation=True"
-        add_nova_opt "melange_host=$M_HOST"
-        add_nova_opt "melange_port=$M_PORT"
+        if is_service_enabled melange; then
+            add_nova_opt "quantum_ipam_lib=nova.network.quantum.melange_ipam_lib"
+            add_nova_opt "use_melange_mac_generation=True"
+            add_nova_opt "melange_host=$M_HOST"
+            add_nova_opt "melange_port=$M_PORT"
+        fi
+
+    elif [[ "$NOVA_USE_QUANTUM_API" = "v2" ]]; then
+        add_nova_opt "network_api_class=nova.network.quantumv2.api.API"
+        add_nova_opt "quantum_admin_username=$Q_ADMIN_USERNAME"
+        add_nova_opt "quantum_admin_password=$SERVICE_PASSWORD"
+        add_nova_opt "quantum_admin_auth_url=$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_AUTH_PORT/v2.0"
+        add_nova_opt "quantum_auth_strategy=$Q_AUTH_STRATEGY"
+        add_nova_opt "quantum_admin_tenant_name=$SERVICE_TENANT_NAME"
+        add_nova_opt "quantum_url=http://$Q_HOST:$Q_PORT"
     fi
 
     if [[ "$Q_PLUGIN" = "openvswitch" ]]; then
@@ -1704,7 +1854,6 @@
     add_nova_opt "libvirt_vif_type=ethernet"
     add_nova_opt "libvirt_vif_driver=$NOVA_VIF_DRIVER"
     add_nova_opt "linuxnet_interface_driver=$LINUXNET_VIF_DRIVER"
-    add_nova_opt "quantum_use_dhcp=True"
 else
     add_nova_opt "network_manager=nova.network.manager.$NET_MAN"
 fi
@@ -1724,6 +1873,7 @@
 fi
 add_nova_opt "sql_connection=$BASE_SQL_CONN/nova?charset=utf8"
 add_nova_opt "libvirt_type=$LIBVIRT_TYPE"
+add_nova_opt "libvirt_cpu_mode=none"
 add_nova_opt "instance_name_template=${INSTANCE_NAME_PREFIX}%08x"
 # 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
@@ -1801,7 +1951,7 @@
 
 if [ "$VIRT_DRIVER" = 'xenserver' ]; then
     read_password XENAPI_PASSWORD "ENTER A PASSWORD TO USE FOR XEN."
-    add_nova_opt "connection_type=xenapi"
+    add_nova_opt "compute_driver=xenapi.XenAPIDriver"
     XENAPI_CONNECTION_URL=${XENAPI_CONNECTION_URL:-"http://169.254.0.1"}
     XENAPI_USER=${XENAPI_USER:-"root"}
     add_nova_opt "xenapi_connection_url=$XENAPI_CONNECTION_URL"
@@ -1812,7 +1962,7 @@
     XEN_FIREWALL_DRIVER=${XEN_FIREWALL_DRIVER:-"nova.virt.firewall.IptablesFirewallDriver"}
     add_nova_opt "firewall_driver=$XEN_FIREWALL_DRIVER"
 else
-    add_nova_opt "connection_type=libvirt"
+    add_nova_opt "compute_driver=libvirt.LibvirtDriver"
     LIBVIRT_FIREWALL_DRIVER=${LIBVIRT_FIREWALL_DRIVER:-"nova.virt.libvirt.firewall.IptablesFirewallDriver"}
     add_nova_opt "firewall_driver=$LIBVIRT_FIREWALL_DRIVER"
 fi
@@ -1827,7 +1977,10 @@
 if is_service_enabled mysql && is_service_enabled nova; then
     # (re)create nova database
     mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'DROP DATABASE IF EXISTS nova;'
-    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE nova;'
+    # Explicitly use latin1: to avoid lp#829209, nova expects the database to
+    # use latin1 by default, and then upgrades the database to utf8 (see the
+    # 082_essex.py in nova)
+    mysql -u$MYSQL_USER -p$MYSQL_PASSWORD -e 'CREATE DATABASE nova CHARACTER SET latin1;'
 
     # (re)create nova database
     $NOVA_DIR/bin/nova-manage db sync
@@ -1902,9 +2055,9 @@
 
         # Add quantum endpoints to service catalog if quantum is enabled
         if is_service_enabled quantum; then
-            echo "catalog.RegionOne.network.publicURL = http://%SERVICE_HOST%:9696/" >> $KEYSTONE_CATALOG
-            echo "catalog.RegionOne.network.adminURL = http://%SERVICE_HOST%:9696/" >> $KEYSTONE_CATALOG
-            echo "catalog.RegionOne.network.internalURL = http://%SERVICE_HOST%:9696/" >> $KEYSTONE_CATALOG
+            echo "catalog.RegionOne.network.publicURL = http://%SERVICE_HOST%:$Q_PORT/" >> $KEYSTONE_CATALOG
+            echo "catalog.RegionOne.network.adminURL = http://%SERVICE_HOST%:$Q_PORT/" >> $KEYSTONE_CATALOG
+            echo "catalog.RegionOne.network.internalURL = http://%SERVICE_HOST%:$Q_PORT/" >> $KEYSTONE_CATALOG
             echo "catalog.RegionOne.network.name = Quantum Service" >> $KEYSTONE_CATALOG
         fi
 
@@ -1928,13 +2081,15 @@
     iniset $KEYSTONE_CONF_DIR/logging.conf logger_root level "DEBUG"
     iniset $KEYSTONE_CONF_DIR/logging.conf logger_root handlers "devel,production"
 
-    # Set up the keystone database
+    # Initialize keystone database
     $KEYSTONE_DIR/bin/keystone-manage db_sync
+    # set up certificates
+    $KEYSTONE_DIR/bin/keystone-manage pki_setup
 
     # launch keystone and wait for it to answer before continuing
     screen_it key "cd $KEYSTONE_DIR && $KEYSTONE_DIR/bin/keystone-all --config-file $KEYSTONE_CONF $KEYSTONE_LOG_CONFIG -d --debug"
     echo "Waiting for keystone to start..."
-    if ! timeout $SERVICE_TIMEOUT sh -c "while http_proxy= wget -O- $KEYSTONE_AUTH_PROTOCOL://$SERVICE_HOST:$KEYSTONE_API_PORT/v2.0/ 2>&1 | grep -q 'refused'; do sleep 1; done"; then
+    if ! timeout $SERVICE_TIMEOUT sh -c "while ! http_proxy= curl -s $KEYSTONE_AUTH_PROTOCOL://$SERVICE_HOST:$KEYSTONE_API_PORT/v2.0/ >/dev/null; do sleep 1; done"; then
       echo "keystone did not start"
       exit 1
     fi
@@ -1946,7 +2101,7 @@
     SERVICE_TOKEN=$SERVICE_TOKEN SERVICE_ENDPOINT=$SERVICE_ENDPOINT SERVICE_HOST=$SERVICE_HOST \
     S3_SERVICE_PORT=$S3_SERVICE_PORT KEYSTONE_CATALOG_BACKEND=$KEYSTONE_CATALOG_BACKEND \
     DEVSTACK_DIR=$TOP_DIR ENABLED_SERVICES=$ENABLED_SERVICES \
-        bash $FILES/keystone_data.sh
+        bash -x $FILES/keystone_data.sh
 
     # Set up auth creds now that keystone is bootstrapped
     export OS_AUTH_URL=$SERVICE_ENDPOINT
@@ -1954,8 +2109,8 @@
     export OS_USERNAME=admin
     export OS_PASSWORD=$ADMIN_PASSWORD
 
-    # create an access key and secret key for nova ec2 register image
-    if is_service_enabled swift && is_service_enabled nova; then
+    # Create an access key and secret key for nova ec2 register image
+    if is_service_enabled swift3 && is_service_enabled nova; then
         NOVA_USER_ID=$(keystone user-list | grep ' nova ' | get_field 1)
         NOVA_TENANT_ID=$(keystone tenant-list | grep " $SERVICE_TENANT_NAME " | get_field 1)
         CREDS=$(keystone ec2-credentials-create --user_id $NOVA_USER_ID --tenant_id $NOVA_TENANT_ID)
@@ -1967,7 +2122,7 @@
     fi
 fi
 
-# launch the nova-api and wait for it to answer before continuing
+# Launch the nova-api and wait for it to answer before continuing
 if is_service_enabled n-api; then
     add_nova_opt "enabled_apis=$NOVA_ENABLED_APIS"
     screen_it n-api "cd $NOVA_DIR && $NOVA_DIR/bin/nova-api"
@@ -1981,14 +2136,24 @@
 # If we're using Quantum (i.e. q-svc is enabled), network creation has to
 # happen after we've started the Quantum service.
 if is_service_enabled mysql && is_service_enabled nova; then
-    # create a small network
-    $NOVA_DIR/bin/nova-manage network create private $FIXED_RANGE 1 $FIXED_NETWORK_SIZE $NETWORK_CREATE_ARGS
+    if [[ "$NOVA_USE_QUANTUM_API" = "v1" ]]; then
+        # Create a small network
+        $NOVA_DIR/bin/nova-manage network create private $FIXED_RANGE 1 $FIXED_NETWORK_SIZE $NETWORK_CREATE_ARGS
 
-    # create some floating ips
-    $NOVA_DIR/bin/nova-manage floating create $FLOATING_RANGE
+        # Create some floating ips
+        $NOVA_DIR/bin/nova-manage floating create $FLOATING_RANGE
 
-    # create a second pool
-    $NOVA_DIR/bin/nova-manage floating create --ip_range=$TEST_FLOATING_RANGE --pool=$TEST_FLOATING_POOL
+        # Create a second pool
+        $NOVA_DIR/bin/nova-manage floating create --ip_range=$TEST_FLOATING_RANGE --pool=$TEST_FLOATING_POOL
+    elif [[ "$NOVA_USE_QUANTUM_API" = "v2" ]]; then
+        TENANT_ID=$(keystone tenant-list | grep " demo " | get_field 1)
+
+        # Create a small network
+        # Since quantum command is executed in admin context at this point,
+        # --tenant_id needs to be specified.
+        NET_ID=$(quantum net-create --tenant_id $TENANT_ID net1 | grep ' id ' | get_field 2)
+        quantum subnet-create --tenant_id $TENANT_ID --ip_version 4 --gateway $NETWORK_GATEWAY $NET_ID $FIXED_RANGE
+    fi
 fi
 
 # Launching nova-compute should be as simple as running ``nova-compute`` but
@@ -2011,11 +2176,12 @@
 screen_it horizon "cd $HORIZON_DIR && sudo tail -f /var/log/$APACHE_NAME/horizon_error.log"
 screen_it swift "cd $SWIFT_DIR && $SWIFT_DIR/bin/swift-proxy-server ${SWIFT_CONFIG_DIR}/proxy-server.conf -v"
 
-# Starting the nova-objectstore only if swift service is not enabled.
+# Starting the nova-objectstore only if swift3 service is not enabled.
 # Swift will act as s3 objectstore.
-is_service_enabled swift || \
+is_service_enabled swift3 || \
     screen_it n-obj "cd $NOVA_DIR && $NOVA_DIR/bin/nova-objectstore"
 
+
 # Install Images
 # ==============
 
diff --git a/stackrc b/stackrc
index 3a19cdb..3bbc475 100644
--- a/stackrc
+++ b/stackrc
@@ -1,6 +1,9 @@
 # Find the other rc files
 RC_DIR=$(cd $(dirname "$BASH_SOURCE") && pwd)
 
+# Destination path for installation
+DEST=/opt/stack
+
 # Specify which services to launch.  These generally correspond to
 # screen tabs. If you like to add other services that are not enabled
 # by default you can append them in your ENABLED_SERVICES variable in
@@ -10,46 +13,50 @@
 #
 # If you like to explicitly remove services you can add a -$service in
 # ENABLED_SERVICES, for example in your localrc to install all defaults but not
-# nova-volume you would just need to set this :
-# ENABLED_SERVICES+=,-n-vol
-ENABLED_SERVICES=g-api,g-reg,key,n-api,n-crt,n-obj,n-cpu,n-net,n-vol,n-sch,n-novnc,n-xvnc,n-cauth,horizon,mysql,rabbit
+# cinder you would just need to set this :
+# ENABLED_SERVICES+=,-cinder
+ENABLED_SERVICES=g-api,g-reg,key,n-api,n-crt,n-obj,n-cpu,n-net,cinder,c-sch,c-api,c-vol,n-sch,n-novnc,n-xvnc,n-cauth,horizon,mysql,rabbit
 
 # Set the default Nova APIs to enable
 NOVA_ENABLED_APIS=ec2,osapi_compute,osapi_volume,metadata
 
+# Base GIT Repo URL
+# Another option is http://review.openstack.org/p
+GIT_BASE=https://github.com
+
 # volume service
-CINDER_REPO=https://github.com/openstack/cinder
+CINDER_REPO=${GIT_BASE}/openstack/cinder
 CINDER_BRANCH=master
 
 # volume client
-CINDERCLIENT_REPO=https://github.com/openstack/python-cinderclient
+CINDERCLIENT_REPO=${GIT_BASE}/openstack/python-cinderclient
 CINDERCLIENT_BRANCH=master
 
 # compute service
-NOVA_REPO=https://github.com/openstack/nova.git
+NOVA_REPO=${GIT_BASE}/openstack/nova.git
 NOVA_BRANCH=master
 
 # storage service
-SWIFT_REPO=https://github.com/openstack/swift.git
+SWIFT_REPO=${GIT_BASE}/openstack/swift.git
 SWIFT_BRANCH=master
 SWIFT3_REPO=https://github.com/fujita/swift3.git
 SWIFT3_BRANCH=master
 
 
 # python swift client library
-SWIFTCLIENT_REPO=https://github.com/openstack/python-swiftclient
+SWIFTCLIENT_REPO=${GIT_BASE}/openstack/python-swiftclient
 SWIFTCLIENT_BRANCH=master
 
 # image catalog service
-GLANCE_REPO=https://github.com/openstack/glance.git
+GLANCE_REPO=${GIT_BASE}/openstack/glance.git
 GLANCE_BRANCH=master
 
 # python glance client library
-GLANCECLIENT_REPO=https://github.com/openstack/python-glanceclient
+GLANCECLIENT_REPO=${GIT_BASE}/openstack/python-glanceclient
 GLANCECLIENT_BRANCH=master
 
 # unified auth system (manages accounts/tokens)
-KEYSTONE_REPO=https://github.com/openstack/keystone.git
+KEYSTONE_REPO=${GIT_BASE}/openstack/keystone.git
 KEYSTONE_BRANCH=master
 
 # a websockets/html5 or flash powered VNC console for vm instances
@@ -57,39 +64,39 @@
 NOVNC_BRANCH=master
 
 # django powered web control panel for openstack
-HORIZON_REPO=https://github.com/openstack/horizon.git
+HORIZON_REPO=${GIT_BASE}/openstack/horizon.git
 HORIZON_BRANCH=master
 
 # python client library to nova that horizon (and others) use
-NOVACLIENT_REPO=https://github.com/openstack/python-novaclient.git
+NOVACLIENT_REPO=${GIT_BASE}/openstack/python-novaclient.git
 NOVACLIENT_BRANCH=master
 
 # Shared openstack python client library
-OPENSTACKCLIENT_REPO=https://github.com/openstack/python-openstackclient.git
+OPENSTACKCLIENT_REPO=${GIT_BASE}/openstack/python-openstackclient.git
 OPENSTACKCLIENT_BRANCH=master
 
 # python keystone client library to nova that horizon uses
-KEYSTONECLIENT_REPO=https://github.com/openstack/python-keystoneclient
+KEYSTONECLIENT_REPO=${GIT_BASE}/openstack/python-keystoneclient
 KEYSTONECLIENT_BRANCH=master
 
 # quantum service
-QUANTUM_REPO=https://github.com/openstack/quantum
+QUANTUM_REPO=${GIT_BASE}/openstack/quantum
 QUANTUM_BRANCH=master
 
 # quantum client
-QUANTUM_CLIENT_REPO=https://github.com/openstack/python-quantumclient
+QUANTUM_CLIENT_REPO=${GIT_BASE}/openstack/python-quantumclient
 QUANTUM_CLIENT_BRANCH=master
 
 # Tempest test suite
-TEMPEST_REPO=https://github.com/openstack/tempest.git
+TEMPEST_REPO=${GIT_BASE}/openstack/tempest.git
 TEMPEST_BRANCH=master
 
 # melange service
-MELANGE_REPO=https://github.com/openstack/melange.git
+MELANGE_REPO=${GIT_BASE}/openstack/melange.git
 MELANGE_BRANCH=master
 
 # python melange client library
-MELANGECLIENT_REPO=https://github.com/openstack/python-melangeclient.git
+MELANGECLIENT_REPO=${GIT_BASE}/openstack/python-melangeclient.git
 MELANGECLIENT_BRANCH=master
 
 # Specify a comma-separated list of uec images to download and install into glance.
@@ -120,3 +127,6 @@
 if [ -f $RC_DIR/localrc ]; then
     source $RC_DIR/localrc
 fi
+
+# 5Gb default volume backing file size
+VOLUME_BACKING_FILE_SIZE=${VOLUME_BACKING_FILE_SIZE:-5130M}
diff --git a/tests/functions.sh b/tests/functions.sh
index e436ed9..f111a48 100755
--- a/tests/functions.sh
+++ b/tests/functions.sh
@@ -143,3 +143,99 @@
 fi
 
 rm test.ini
+
+# Enabling/disabling services
+
+echo "Testing enable_service()"
+
+function test_enable_service() {
+    local start="$1"
+    local add="$2"
+    local finish="$3"
+
+    ENABLED_SERVICES="$start"
+    enable_service $add
+    if [ "$ENABLED_SERVICES" = "$finish" ]
+    then
+        echo "OK: $start + $add -> $ENABLED_SERVICES"
+    else
+        echo "changing $start to $finish with $add failed: $ENABLED_SERVICES"
+    fi
+}
+
+test_enable_service '' a 'a'
+test_enable_service 'a' b 'a,b'
+test_enable_service 'a,b' c 'a,b,c'
+test_enable_service 'a,b' c 'a,b,c'
+test_enable_service 'a,b,' c 'a,b,c'
+test_enable_service 'a,b' c,d 'a,b,c,d'
+test_enable_service 'a,b' "c d" 'a,b,c,d'
+test_enable_service 'a,b,c' c 'a,b,c'
+
+test_enable_service 'a,b,-c' c 'a,b'
+test_enable_service 'a,b,c' -c 'a,b'
+
+function test_disable_service() {
+    local start="$1"
+    local del="$2"
+    local finish="$3"
+
+    ENABLED_SERVICES="$start"
+    disable_service "$del"
+    if [ "$ENABLED_SERVICES" = "$finish" ]
+    then
+        echo "OK: $start - $del -> $ENABLED_SERVICES"
+    else
+        echo "changing $start to $finish with $del failed: $ENABLED_SERVICES"
+    fi
+}
+
+echo "Testing disable_service()"
+test_disable_service 'a,b,c' a 'b,c'
+test_disable_service 'a,b,c' b 'a,c'
+test_disable_service 'a,b,c' c 'a,b'
+
+test_disable_service 'a,b,c' a 'b,c'
+test_disable_service 'b,c' b 'c'
+test_disable_service 'c' c ''
+test_disable_service '' d ''
+
+test_disable_service 'a,b,c,' c 'a,b'
+test_disable_service 'a,b' c 'a,b'
+
+
+echo "Testing disable_all_services()"
+ENABLED_SERVICES=a,b,c
+disable_all_services
+
+if [[ -z "$ENABLED_SERVICES" ]]
+then
+    echo "OK"
+else
+    echo "disabling all services FAILED: $ENABLED_SERVICES"
+fi
+
+echo "Testing disable_negated_services()"
+
+
+function test_disable_negated_services() {
+    local start="$1"
+    local finish="$2"
+
+    ENABLED_SERVICES="$start"
+    disable_negated_services
+    if [ "$ENABLED_SERVICES" = "$finish" ]
+    then
+        echo "OK: $start + $add -> $ENABLED_SERVICES"
+    else
+        echo "changing $start to $finish failed: $ENABLED_SERVICES"
+    fi
+}
+
+test_disable_negated_services '-a' ''
+test_disable_negated_services '-a,a' ''
+test_disable_negated_services '-a,-a' ''
+test_disable_negated_services 'a,-a' ''
+test_disable_negated_services 'b,a,-a' 'b'
+test_disable_negated_services 'a,b,-a' 'b'
+test_disable_negated_services 'a,-a,b' 'b'
diff --git a/tools/build_bm.sh b/tools/build_bm.sh
index 44cf303..ab0ba0e 100755
--- a/tools/build_bm.sh
+++ b/tools/build_bm.sh
@@ -1,7 +1,17 @@
 #!/usr/bin/env bash
+
+# **build_bm.sh**
+
 # Build an OpenStack install on a bare metal machine.
 set +x
 
+# Keep track of the current directory
+TOOLS_DIR=$(cd $(dirname "$0") && pwd)
+TOP_DIR=$(cd $TOOLS_DIR/..; pwd)
+
+# Import common functions
+source $TOP_DIR/functions
+
 # Source params
 source ./stackrc
 
diff --git a/tools/build_bm_multi.sh b/tools/build_bm_multi.sh
index 133d537..f1242ee 100755
--- a/tools/build_bm_multi.sh
+++ b/tools/build_bm_multi.sh
@@ -1,4 +1,7 @@
 #!/usr/bin/env bash
+
+# **build_bm_multi.sh**
+
 # Build an OpenStack install on several bare metal machines.
 SHELL_AFTER_RUN=no
 
diff --git a/tools/build_pxe_env.sh b/tools/build_pxe_env.sh
index d01dad0..e6f98b4 100755
--- a/tools/build_pxe_env.sh
+++ b/tools/build_pxe_env.sh
@@ -1,5 +1,8 @@
 #!/bin/bash -e
-# build_pxe_env.sh - Create a PXE boot environment
+
+# **build_pxe_env.sh**
+
+# Create a PXE boot environment
 #
 # build_pxe_env.sh destdir
 #
diff --git a/tools/build_ramdisk.sh b/tools/build_ramdisk.sh
index 7c1600b..8e2c0be 100755
--- a/tools/build_ramdisk.sh
+++ b/tools/build_ramdisk.sh
@@ -1,7 +1,10 @@
 #!/bin/bash
-# build_ramdisk.sh - Build RAM disk images
 
-# exit on error to stop unexpected errors
+# **build_ramdisk.sh**
+
+# Build RAM disk images
+
+# Exit on error to stop unexpected errors
 set -o errexit
 
 if [ ! "$#" -eq "1" ]; then
@@ -84,7 +87,7 @@
 # Finds the next available NBD device
 # Exits script if error connecting or none free
 # map_nbd image
-# returns full nbd device path
+# Returns full nbd device path
 function map_nbd {
     for i in `seq 0 15`; do
         if [ ! -e /sys/block/nbd$i/pid ]; then
@@ -105,7 +108,7 @@
     echo $NBD
 }
 
-# prime image with as many apt/pips as we can
+# Prime image with as many apt/pips as we can
 DEV_FILE=$CACHEDIR/$DIST_NAME-dev.img
 DEV_FILE_TMP=`mktemp $DEV_FILE.XXXXXX`
 if [ ! -r $DEV_FILE ]; then
@@ -127,11 +130,11 @@
     mkdir -p $MNTDIR/$DEST
     chroot $MNTDIR chown stack $DEST
 
-    # a simple password - pass
+    # A simple password - pass
     echo stack:pass | chroot $MNTDIR chpasswd
     echo root:$ROOT_PASSWORD | chroot $MNTDIR chpasswd
 
-    # and has sudo ability (in the future this should be limited to only what
+    # And has sudo ability (in the future this should be limited to only what
     # stack requires)
     echo "stack ALL=(ALL) NOPASSWD: ALL" >> $MNTDIR/etc/sudoers
 
@@ -143,7 +146,8 @@
 fi
 rm -f $DEV_FILE_TMP
 
-# clone git repositories onto the system
+
+# Clone git repositories onto the system
 # ======================================
 
 IMG_FILE_TMP=`mktemp $IMG_FILE.XXXXXX`
diff --git a/tools/build_tempest.sh b/tools/build_tempest.sh
index 230e8f9..e72355c 100755
--- a/tools/build_tempest.sh
+++ b/tools/build_tempest.sh
@@ -1,7 +1,8 @@
 #!/usr/bin/env bash
 #
-# build_tempest.sh - Checkout and prepare a Tempest repo
-#                    (https://github.com/openstack/tempest.git)
+# **build_tempest.sh**
+
+# Checkout and prepare a Tempest repo: https://github.com/openstack/tempest.git
 
 function usage {
     echo "$0 - Check out and prepare a Tempest repo"
diff --git a/tools/build_uec.sh b/tools/build_uec.sh
index 35a4d6d..48819c9 100755
--- a/tools/build_uec.sh
+++ b/tools/build_uec.sh
@@ -1,5 +1,7 @@
 #!/usr/bin/env bash
 
+# **build_uec.sh**
+
 # Make sure that we have the proper version of ubuntu (only works on oneiric)
 if ! egrep -q "oneiric" /etc/lsb-release; then
     echo "This script only works with ubuntu oneiric."
diff --git a/tools/build_uec_ramdisk.sh b/tools/build_uec_ramdisk.sh
index 32f90c0..150ecab 100755
--- a/tools/build_uec_ramdisk.sh
+++ b/tools/build_uec_ramdisk.sh
@@ -1,7 +1,10 @@
 #!/usr/bin/env bash
-# build_uec_ramdisk.sh - Build RAM disk images based on UEC image
 
-# exit on error to stop unexpected errors
+# **build_uec_ramdisk.sh**
+
+# Build RAM disk images based on UEC image
+
+# Exit on error to stop unexpected errors
 set -o errexit
 
 if [ ! "$#" -eq "1" ]; then
@@ -58,7 +61,7 @@
 # Configure how large the VM should be
 GUEST_SIZE=${GUEST_SIZE:-2G}
 
-# exit on error to stop unexpected errors
+# Exit on error to stop unexpected errors
 set -o errexit
 set -o xtrace
 
diff --git a/tools/build_usb_boot.sh b/tools/build_usb_boot.sh
index cca2a68..f64b7b6 100755
--- a/tools/build_usb_boot.sh
+++ b/tools/build_usb_boot.sh
@@ -1,5 +1,8 @@
 #!/bin/bash -e
-# build_usb_boot.sh - Create a syslinux boot environment
+
+# **build_usb_boot.sh**
+
+# Create a syslinux boot environment
 #
 # build_usb_boot.sh destdev
 #
diff --git a/tools/configure_tempest.sh b/tools/configure_tempest.sh
index 7a72045..4d029d8 100755
--- a/tools/configure_tempest.sh
+++ b/tools/configure_tempest.sh
@@ -1,6 +1,8 @@
 #!/usr/bin/env bash
 #
-# configure_tempest.sh - Build a tempest configuration file from devstack
+# **configure_tempest.sh**
+
+# Build a tempest configuration file from devstack
 
 echo "**************************************************"
 echo "Configuring Tempest"
@@ -50,6 +52,7 @@
 # Where Openstack code lives
 DEST=${DEST:-/opt/stack}
 
+NOVA_SOURCE_DIR=$DEST/nova
 TEMPEST_DIR=$DEST/tempest
 CONFIG_DIR=$TEMPEST_DIR/etc
 TEMPEST_CONF=$CONFIG_DIR/tempest.conf
@@ -93,9 +96,13 @@
 # copy every time, because the image UUIDS are going to change
 cp $TEMPEST_CONF.tpl $TEMPEST_CONF
 
-ADMIN_USERNAME=${ADMIN_USERNAME:-admin}
-ADMIN_PASSWORD=${ADMIN_PASSWORD:-secrete}
-ADMIN_TENANT_NAME=${ADMIN_TENANT:-admin}
+COMPUTE_ADMIN_USERNAME=${ADMIN_USERNAME:-admin}
+COMPUTE_ADMIN_PASSWORD=${ADMIN_PASSWORD:-secrete}
+COMPUTE_ADMIN_TENANT_NAME=${ADMIN_TENANT:-admin}
+
+IDENTITY_ADMIN_USERNAME=${ADMIN_USERNAME:-admin}
+IDENTITY_ADMIN_PASSWORD=${ADMIN_PASSWORD:-secrete}
+IDENTITY_ADMIN_TENANT_NAME=${ADMIN_TENANT:-admin}
 
 IDENTITY_USE_SSL=${IDENTITY_USE_SSL:-False}
 IDENTITY_HOST=${IDENTITY_HOST:-127.0.0.1}
@@ -105,6 +112,7 @@
 # from the Tempest configuration file entirely...
 IDENTITY_PATH=${IDENTITY_PATH:-tokens}
 IDENTITY_STRATEGY=${IDENTITY_STRATEGY:-keystone}
+IDENTITY_CATALOG_TYPE=identity
 
 # We use regular, non-admin users in Tempest for the USERNAME
 # substitutions and use ADMIN_USERNAME et al for the admin stuff.
@@ -126,15 +134,39 @@
 # Do any of the following need to be configurable?
 COMPUTE_CATALOG_TYPE=compute
 COMPUTE_CREATE_IMAGE_ENABLED=True
-COMPUTE_RESIZE_AVAILABLE=False  # not supported with QEMU...
+COMPUTE_ALLOW_TENANT_ISOLATION=True
+COMPUTE_RESIZE_AVAILABLE=False
+COMPUTE_CHANGE_PASSWORD_AVAILABLE=False  # not supported with QEMU...
 COMPUTE_LOG_LEVEL=ERROR
-BUILD_INTERVAL=10
-BUILD_TIMEOUT=600
+BUILD_INTERVAL=3
+BUILD_TIMEOUT=400
+RUN_SSH=True
+SSH_USER=$OS_USERNAME
+NETWORK_FOR_SSH=private
+IP_VERSION_FOR_SSH=4
+SSH_TIMEOUT=4
+# Whitebox testing configuration for Compute...
+COMPUTE_WHITEBOX_ENABLED=True
+COMPUTE_SOURCE_DIR=$NOVA_SOURCE_DIR
+COMPUTE_BIN_DIR=/usr/bin/nova
+COMPUTE_CONFIG_PATH=/etc/nova/nova.conf
+# TODO(jaypipes): Create the key file here... right now, no whitebox
+# tests actually use a key.
+COMPUTE_PATH_TO_PRIVATE_KEY=$TEMPEST_DIR/id_rsa
+COMPUTE_DB_URI=mysql://root:$MYSQL_PASSWORD@localhost/nova
 
 # Image test configuration options...
 IMAGE_HOST=${IMAGE_HOST:-127.0.0.1}
 IMAGE_PORT=${IMAGE_PORT:-9292}
-IMAGE_API_VERSION="1"
+IMAGE_API_VERSION=1
+IMAGE_CATALOG_TYPE=image
+
+# Network API test configuration
+NETWORK_CATALOG_TYPE=network
+NETWORK_API_VERSION=2.0
+
+# Volume API test configuration
+VOLUME_CATALOG_TYPE=volume
 
 sed -e "
     s,%IDENTITY_USE_SSL%,$IDENTITY_USE_SSL,g;
@@ -143,6 +175,7 @@
     s,%IDENTITY_API_VERSION%,$IDENTITY_API_VERSION,g;
     s,%IDENTITY_PATH%,$IDENTITY_PATH,g;
     s,%IDENTITY_STRATEGY%,$IDENTITY_STRATEGY,g;
+    s,%IDENTITY_CATALOG_TYPE%,$IDENTITY_CATALOG_TYPE,g;
     s,%USERNAME%,$OS_USERNAME,g;
     s,%PASSWORD%,$OS_PASSWORD,g;
     s,%TENANT_NAME%,$OS_TENANT_NAME,g;
@@ -150,25 +183,41 @@
     s,%ALT_PASSWORD%,$ALT_PASSWORD,g;
     s,%ALT_TENANT_NAME%,$ALT_TENANT_NAME,g;
     s,%COMPUTE_CATALOG_TYPE%,$COMPUTE_CATALOG_TYPE,g;
+    s,%COMPUTE_ALLOW_TENANT_ISOLATION%,$COMPUTE_ALLOW_TENANT_ISOLATION,g;
     s,%COMPUTE_CREATE_IMAGE_ENABLED%,$COMPUTE_CREATE_IMAGE_ENABLED,g;
     s,%COMPUTE_RESIZE_AVAILABLE%,$COMPUTE_RESIZE_AVAILABLE,g;
+    s,%COMPUTE_CHANGE_PASSWORD_AVAILABLE%,$COMPUTE_CHANGE_PASSWORD_AVAILABLE,g;
+    s,%COMPUTE_WHITEBOX_ENABLED%,$COMPUTE_WHITEBOX_ENABLED,g;
     s,%COMPUTE_LOG_LEVEL%,$COMPUTE_LOG_LEVEL,g;
     s,%BUILD_INTERVAL%,$BUILD_INTERVAL,g;
     s,%BUILD_TIMEOUT%,$BUILD_TIMEOUT,g;
+    s,%RUN_SSH%,$RUN_SSH,g;
+    s,%SSH_USER%,$SSH_USER,g;
+    s,%NETWORK_FOR_SSH%,$NETWORK_FOR_SSH,g;
+    s,%IP_VERSION_FOR_SSH%,$IP_VERSION_FOR_SSH,g;
+    s,%SSH_TIMEOUT%,$SSH_TIMEOUT,g;
     s,%IMAGE_ID%,$IMAGE_UUID,g;
     s,%IMAGE_ID_ALT%,$IMAGE_UUID_ALT,g;
     s,%FLAVOR_REF%,$FLAVOR_REF,g;
     s,%FLAVOR_REF_ALT%,$FLAVOR_REF_ALT,g;
+    s,%COMPUTE_CONFIG_PATH%,$COMPUTE_CONFIG_PATH,g;
+    s,%COMPUTE_SOURCE_DIR%,$COMPUTE_SOURCE_DIR,g;
+    s,%COMPUTE_BIN_DIR%,$COMPUTE_BIN_DIR,g;
+    s,%COMPUTE_PATH_TO_PRIVATE_KEY%,$COMPUTE_PATH_TO_PRIVATE_KEY,g;
+    s,%COMPUTE_DB_URI%,$COMPUTE_DB_URI,g;
     s,%IMAGE_HOST%,$IMAGE_HOST,g;
     s,%IMAGE_PORT%,$IMAGE_PORT,g;
     s,%IMAGE_API_VERSION%,$IMAGE_API_VERSION,g;
-    s,%COMPUTE_ADMIN_USERNAME%,$ADMIN_USERNAME,g;
-    s,%COMPUTE_ADMIN_PASSWORD%,$ADMIN_PASSWORD,g;
-    s,%COMPUTE_ADMIN_TENANT_NAME%,$ADMIN_TENANT_NAME,g;
-    s,%IDENTITY_ADMIN_USERNAME%,$ADMIN_USERNAME,g;
-    s,%IDENTITY_ADMIN_PASSWORD%,$ADMIN_PASSWORD,g;
-    s,%IDENTITY_ADMIN_TENANT_NAME%,$ADMIN_TENANT_NAME,g;
-    s,%COMPUTE_ALLOW_TENANT_ISOLATION%,true,g;
+    s,%IMAGE_CATALOG_TYPE%,$IMAGE_CATALOG_TYPE,g;
+    s,%COMPUTE_ADMIN_USERNAME%,$COMPUTE_ADMIN_USERNAME,g;
+    s,%COMPUTE_ADMIN_PASSWORD%,$COMPUTE_ADMIN_PASSWORD,g;
+    s,%COMPUTE_ADMIN_TENANT_NAME%,$COMPUTE_ADMIN_TENANT_NAME,g;
+    s,%IDENTITY_ADMIN_USERNAME%,$IDENTITY_ADMIN_USERNAME,g;
+    s,%IDENTITY_ADMIN_PASSWORD%,$IDENTITY_ADMIN_PASSWORD,g;
+    s,%IDENTITY_ADMIN_TENANT_NAME%,$IDENTITY_ADMIN_TENANT_NAME,g;
+    s,%NETWORK_CATALOG_TYPE%,$NETWORK_CATALOG_TYPE,g;
+    s,%NETWORK_API_VERSION%,$NETWORK_API_VERSION,g;
+    s,%VOLUME_CATALOG_TYPE%,$VOLUME_CATALOG_TYPE,g;
 " -i $TEMPEST_CONF
 
 echo "Created tempest configuration file:"
diff --git a/tools/copy_dev_environment_to_uec.sh b/tools/copy_dev_environment_to_uec.sh
index d5687dc..683a0d6 100755
--- a/tools/copy_dev_environment_to_uec.sh
+++ b/tools/copy_dev_environment_to_uec.sh
@@ -1,5 +1,7 @@
 #!/usr/bin/env bash
 
+# **copy_dev_environment_to_uec.sh**
+
 # Echo commands
 set -o xtrace
 
diff --git a/tools/get_uec_image.sh b/tools/get_uec_image.sh
index 0963074..ca74a03 100755
--- a/tools/get_uec_image.sh
+++ b/tools/get_uec_image.sh
@@ -1,5 +1,8 @@
 #!/bin/bash
-# get_uec_image.sh - Prepare Ubuntu UEC images
+
+# **get_uec_image.sh**
+
+# Download and prepare Ubuntu UEC images
 
 CACHEDIR=${CACHEDIR:-/opt/stack/cache}
 ROOTSIZE=${ROOTSIZE:-2000}
@@ -11,12 +14,12 @@
 # Import common functions
 . $TOP_DIR/functions
 
-# exit on error to stop unexpected errors
+# Exit on error to stop unexpected errors
 set -o errexit
 set -o xtrace
 
 usage() {
-    echo "Usage: $0 - Fetch and prepare Ubuntu images"
+    echo "Usage: $0 - Download and prepare Ubuntu UEC images"
     echo ""
     echo "$0 [-r rootsize] release imagefile [kernel]"
     echo ""
diff --git a/tools/info.sh b/tools/info.sh
index edff617..bf40e82 100755
--- a/tools/info.sh
+++ b/tools/info.sh
@@ -1,5 +1,8 @@
 #!/usr/bin/env bash
-# info.sh - Produce a report on the state of devstack installs
+
+# **info.sh**
+
+# Produce a report on the state of devstack installs
 #
 # Output fields are separated with '|' chars
 # Output types are git,localrc,os,pip,pkg:
@@ -25,6 +28,9 @@
 TOP_DIR=$(cd $TOOLS_DIR/..; pwd)
 cd $TOP_DIR
 
+# Import common functions
+source $TOP_DIR/functions
+
 # Source params
 source $TOP_DIR/stackrc
 
@@ -35,6 +41,21 @@
     exit 1
 fi
 
+
+# OS
+# --
+
+# Determine what OS we're using
+GetDistro
+
+echo "os|distro=$DISTRO"
+echo "os|vendor=$os_VENDOR"
+echo "os|release=$os_RELEASE"
+if [ -n "$os_UPDATE" ]; then
+    echo "os|version=$os_UPDATE"
+fi
+
+
 # Repos
 # -----
 
@@ -59,123 +80,44 @@
     fi
 done
 
-# OS
-# --
-
-GetOSInfo() {
-    # Figure out which vedor we are
-    if [ -r /etc/lsb-release ]; then
-        . /etc/lsb-release
-        VENDORNAME=$DISTRIB_ID
-        RELEASE=$DISTRIB_RELEASE
-    else
-        for r in RedHat CentOS Fedora; do
-            VENDORPKG="`echo $r | tr [:upper:] [:lower:]`-release"
-            VENDORNAME=$r
-            RELEASE=`rpm -q --queryformat '%{VERSION}' $VENDORPKG`
-            if [ $? = 0 ]; then
-                break
-            fi
-            VENDORNAME=""
-        done
-        # Get update level
-        if [ -n "`grep Update /etc/redhat-release`" ]; then
-            # Get update
-            UPDATE=`cat /etc/redhat-release | sed s/.*Update\ // | sed s/\)$//`
-        else
-            # Assume update 0
-            UPDATE=0
-        fi
-    fi
-
-    echo "os|vendor=$VENDORNAME"
-    echo "os|release=$RELEASE"
-    if [ -n "$UPDATE" ]; then
-        echo "os|version=$UPDATE"
-    fi
-}
-
-GetOSInfo
 
 # Packages
 # --------
 
 # - We are going to check packages only for the services needed.
 # - We are parsing the packages files and detecting metadatas.
-#  - If we have the meta-keyword dist:DISTRO or
-#    dist:DISTRO1,DISTRO2 it will be installed only for those
-#    distros (case insensitive).
-function get_packages() {
-    local file_to_parse="general"
-    local service
 
-    for service in ${ENABLED_SERVICES//,/ }; do
-        # Allow individual services to specify dependencies
-        if [[ -e $FILES/apts/${service} ]]; then
-            file_to_parse="${file_to_parse} $service"
-        fi
-        if [[ $service == n-* ]]; then
-            if [[ ! $file_to_parse =~ nova ]]; then
-                file_to_parse="${file_to_parse} nova"
-            fi
-        elif [[ $service == g-* ]]; then
-            if [[ ! $file_to_parse =~ glance ]]; then
-                file_to_parse="${file_to_parse} glance"
-            fi
-        elif [[ $service == key* ]]; then
-            if [[ ! $file_to_parse =~ keystone ]]; then
-                file_to_parse="${file_to_parse} keystone"
-            fi
-        fi
-    done
+if [[ "$os_PACKAGE" = "deb" ]]; then
+    PKG_DIR=$FILES/apts
+else
+    PKG_DIR=$FILES/rpms
+fi
 
-    for file in ${file_to_parse}; do
-        local fname=${FILES}/apts/${file}
-        local OIFS line package distros distro
-        [[ -e $fname ]] || { echo "missing: $fname"; exit 1; }
-
-        OIFS=$IFS
-        IFS=$'\n'
-        for line in $(<${fname}); do
-            if [[ $line =~ (.*)#.*dist:([^ ]*) ]]; then # We are using BASH regexp matching feature.
-                        package=${BASH_REMATCH[1]}
-                        distros=${BASH_REMATCH[2]}
-                        for distro in ${distros//,/ }; do  #In bash ${VAR,,} will lowecase VAR
-                            [[ ${distro,,} == ${DISTRO,,} ]] && echo $package
-                        done
-                        continue
-            fi
-
-            echo ${line%#*}
-        done
-        IFS=$OIFS
-    done
-}
-
-for p in $(get_packages); do
-    ver=$(dpkg -s $p 2>/dev/null | grep '^Version: ' | cut -d' ' -f2)
+for p in $(get_packages $PKG_DIR); do
+    if [[ "$os_PACKAGE" = "deb" ]]; then
+        ver=$(dpkg -s $p 2>/dev/null | grep '^Version: ' | cut -d' ' -f2)
+    else
+        ver=$(rpm -q --queryformat "%{VERSION}-%{RELEASE}\n" $p)
+    fi
     echo "pkg|${p}|${ver}"
 done
 
+
 # Pips
 # ----
 
-function get_pips() {
-    cat $FILES/pips/* | uniq
-}
+if [[ "$os_PACKAGE" = "deb" ]]; then
+    CMD_PIP=/usr/bin/pip
+else
+    CMD_PIP=/usr/bin/pip-python
+fi
 
 # Pip tells us what is currently installed
 FREEZE_FILE=$(mktemp --tmpdir freeze.XXXXXX)
-pip freeze >$FREEZE_FILE 2>/dev/null
+$CMD_PIP freeze >$FREEZE_FILE 2>/dev/null
 
 # Loop through our requirements and look for matches
-for p in $(get_pips); do
-    [[ "$p" = "-e" ]] && continue
-    if [[ "$p" =~ \+?([^#]*)#? ]]; then
-         # Get the URL from a remote reference
-         p=${BASH_REMATCH[1]}
-    fi
-    line="`grep -i $p $FREEZE_FILE`"
+while read line; do
     if [[ -n "$line" ]]; then
         if [[ "$line" =~ \+(.*)@(.*)#egg=(.*) ]]; then
             # Handle URLs
@@ -196,10 +138,11 @@
         #echo "unknown: $p"
         continue
     fi
-done
+done <$FREEZE_FILE
 
 rm $FREEZE_FILE
 
+
 # localrc
 # -------
 
@@ -209,5 +152,5 @@
         /PASSWORD/d;
         /^#/d;
         s/^/localrc\|/;
-    ' $TOP_DIR/localrc | sort
+    ' $TOP_DIR/localrc
 fi
diff --git a/tools/install_openvpn.sh b/tools/install_openvpn.sh
index 44eee72..2f52aa1 100755
--- a/tools/install_openvpn.sh
+++ b/tools/install_openvpn.sh
@@ -1,5 +1,8 @@
 #!/bin/bash
-# install_openvpn.sh - Install OpenVPN and generate required certificates
+
+# **install_openvpn.sh**
+
+# Install OpenVPN and generate required certificates
 #
 # install_openvpn.sh --client name
 # install_openvpn.sh --server [name]
diff --git a/tools/warm_apts_and_pips_for_uec.sh b/tools/warm_apts_and_pips_for_uec.sh
index 23a28de..fe389ff 100755
--- a/tools/warm_apts_and_pips_for_uec.sh
+++ b/tools/warm_apts_and_pips_for_uec.sh
@@ -1,5 +1,7 @@
 #!/usr/bin/env bash
 
+# **warm_apts_and_pips_for_uec.sh**
+
 # Echo commands
 set -o xtrace
 
diff --git a/tools/xen/install_os_domU.sh b/tools/xen/install_os_domU.sh
index 352f63a..19453c1 100755
--- a/tools/xen/install_os_domU.sh
+++ b/tools/xen/install_os_domU.sh
@@ -57,8 +57,9 @@
 fi
 
 # get nova
-wget https://github.com/openstack/nova/zipball/master --no-check-certificate
-unzip -o master -d ./nova
+nova_zipball=$(echo $NOVA_REPO | sed "s:\.git$::;s:$:/zipball/$NOVA_BRANCH:g")
+wget $nova_zipball -O nova-zipball --no-check-certificate
+unzip -o nova-zipball  -d ./nova
 
 # install xapi plugins
 XAPI_PLUGIN_DIR=/etc/xapi.d/plugins/
diff --git a/unstack.sh b/unstack.sh
index 879f842..6a55a0a 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -1,5 +1,7 @@
 #!/usr/bin/env bash
-#
+
+# **unstack.sh**
+
 # Stops that which is started by ``stack.sh`` (mostly)
 # mysql and rabbit are left running as OpenStack code refreshes
 # do not require them to be restarted.
@@ -61,3 +63,8 @@
         stop_service mysql
     fi
 fi
+
+# Quantum dhcp agent runs dnsmasq
+if is_service_enabled q-dhcp; then
+    sudo kill -9 $(ps aux | awk '/[d]nsmasq.+interface=tap/ { print $2 }')
+fi