Merge "Install agent packages when running the Nicira plugin."
diff --git a/README.md b/README.md
index 8573638..905a54d 100644
--- a/README.md
+++ b/README.md
@@ -122,6 +122,19 @@
 
 Then run `stack.sh` as normal.
 
+devstack supports adding specific Quantum configuration flags to both the Open vSwitch and LinuxBridge plugin configuration files. To make use of this feature, the following variables are defined and can be configured in your `localrc` file:
+
+    Variable Name             Plugin Config File Section Modified
+    -------------------------------------------------------------------------------------
+    Q_SRV_EXTRA_OPTS          `OVS` (for Open Vswitch) or `LINUX_BRIDGE` (for LinuxBridge)
+    Q_AGENT_EXTRA_AGENT_OPTS  AGENT
+    Q_AGENT_EXTRA_SRV_OPTS    `OVS` (for Open Vswitch) or `LINUX_BRIDGE` (for LinuxBridge)
+
+An example of using the variables in your `localrc` is below:
+
+    Q_AGENT_EXTRA_AGENT_OPTS=(tunnel_type=vxlan vxlan_udp_port=8472)
+    Q_SRV_EXTRA_OPTS=(tenant_network_type=vxlan)
+
 # Tempest
 
 If tempest has been successfully configured, a basic set of smoke tests can be run as follows:
diff --git a/exercises/euca.sh b/exercises/euca.sh
index d704279..16b5f8e 100755
--- a/exercises/euca.sh
+++ b/exercises/euca.sh
@@ -162,7 +162,7 @@
 # case changed with bug/836978. Requesting the status of an invalid instance
 # will now return an error message including the instance id, so we need to
 # filter that out.
-if ! timeout $TERMINATE_TIMEOUT sh -c "while euca-describe-instances $INSTANCE | grep -ve \"\\\(InstanceNotFound\\\|InvalidInstanceID\[.\]NotFound\\\)\" | grep -q $INSTANCE; do sleep 1; done"; then
+if ! timeout $TERMINATE_TIMEOUT sh -c "while euca-describe-instances $INSTANCE | grep -ve '\(InstanceNotFound\|InvalidInstanceID\.NotFound\)' | grep -q $INSTANCE; do sleep 1; done"; then
     die $LINENO "server didn't terminate within $TERMINATE_TIMEOUT seconds"
 fi
 
diff --git a/functions b/functions
index dfde7dc..1257024 100644
--- a/functions
+++ b/functions
@@ -200,6 +200,7 @@
     echo "$pkg_dir"
 }
 
+
 # get_packages() collects a list of package names of any type from the
 # prerequisite files in ``files/{apts|rpms}``.  The list is intended
 # to be passed to a package installer such as apt or yum.
@@ -390,42 +391,6 @@
     export os_VENDOR os_RELEASE os_UPDATE os_PACKAGE os_CODENAME
 }
 
-# git update using reference as a branch.
-# git_update_branch ref
-function git_update_branch() {
-
-    GIT_BRANCH=$1
-
-    git checkout -f origin/$GIT_BRANCH
-    # a local branch might not exist
-    git branch -D $GIT_BRANCH || true
-    git checkout -b $GIT_BRANCH
-}
-
-
-# git update using reference as a tag. Be careful editing source at that repo
-# as working copy will be in a detached mode
-# git_update_tag ref
-function git_update_tag() {
-
-    GIT_TAG=$1
-
-    git tag -d $GIT_TAG
-    # fetching given tag only
-    git fetch origin tag $GIT_TAG
-    git checkout -f $GIT_TAG
-}
-
-
-# git update using reference as a branch.
-# git_update_remote_branch ref
-function git_update_remote_branch() {
-
-    GIT_BRANCH=$1
-
-    git checkout -b $GIT_BRANCH -t origin/$GIT_BRANCH
-}
-
 
 # Translate the OS version values into common nomenclature
 # Sets ``DISTRO`` from the ``os_*`` values
@@ -457,19 +422,8 @@
 }
 
 
-# Determine if current distribution is an Ubuntu-based distribution.
-# It will also detect non-Ubuntu but Debian-based distros; this is not an issue
-# since Debian and Ubuntu should be compatible.
-# is_ubuntu
-function is_ubuntu {
-    if [[ -z "$os_PACKAGE" ]]; then
-        GetOSVersion
-    fi
-    [ "$os_PACKAGE" = "deb" ]
-}
-
 # Determine if current distribution is a Fedora-based distribution
-# (Fedora, RHEL, CentOS).
+# (Fedora, RHEL, CentOS, etc).
 # is_fedora
 function is_fedora {
     if [[ -z "$os_VENDOR" ]]; then
@@ -479,6 +433,7 @@
     [ "$os_VENDOR" = "Fedora" ] || [ "$os_VENDOR" = "Red Hat" ] || [ "$os_VENDOR" = "CentOS" ]
 }
 
+
 # Determine if current distribution is a SUSE-based distribution
 # (openSUSE, SLE).
 # is_suse
@@ -491,6 +446,17 @@
 }
 
 
+# Determine if current distribution is an Ubuntu-based distribution
+# It will also detect non-Ubuntu but Debian-based distros
+# is_ubuntu
+function is_ubuntu {
+    if [[ -z "$os_PACKAGE" ]]; then
+        GetOSVersion
+    fi
+    [ "$os_PACKAGE" = "deb" ]
+}
+
+
 # Exit after outputting a message about the distribution not being supported.
 # exit_distro_not_supported [optional-string-telling-what-is-missing]
 function exit_distro_not_supported {
@@ -565,6 +531,43 @@
 }
 
 
+# git update using reference as a branch.
+# git_update_branch ref
+function git_update_branch() {
+
+    GIT_BRANCH=$1
+
+    git checkout -f origin/$GIT_BRANCH
+    # a local branch might not exist
+    git branch -D $GIT_BRANCH || true
+    git checkout -b $GIT_BRANCH
+}
+
+
+# git update using reference as a branch.
+# git_update_remote_branch ref
+function git_update_remote_branch() {
+
+    GIT_BRANCH=$1
+
+    git checkout -b $GIT_BRANCH -t origin/$GIT_BRANCH
+}
+
+
+# git update using reference as a tag. Be careful editing source at that repo
+# as working copy will be in a detached mode
+# git_update_tag ref
+function git_update_tag() {
+
+    GIT_TAG=$1
+
+    git tag -d $GIT_TAG
+    # fetching given tag only
+    git fetch origin tag $GIT_TAG
+    git checkout -f $GIT_TAG
+}
+
+
 # Comment an option in an INI file
 # inicomment config-file section option
 function inicomment() {
@@ -1020,6 +1023,7 @@
     fi
 }
 
+
 # Helper to remove the *.failure files under $SERVICE_DIR/$SCREEN_NAME
 # This is used for service_check when all the screen_it are called finished
 # init_service_check
@@ -1034,6 +1038,7 @@
     rm -f "$SERVICE_DIR/$SCREEN_NAME"/*.failure
 }
 
+
 # Helper to get the status of each running service
 # service_check
 function service_check() {
@@ -1062,6 +1067,7 @@
     fi
 }
 
+
 # ``pip install`` the dependencies of the package before ``setup.py develop``
 # so pip and not distutils processes the dependency chain
 # Uses globals ``TRACK_DEPENDES``, ``*_proxy`
@@ -1242,6 +1248,7 @@
     fi
 }
 
+
 # Set the database backend to use
 # When called from stackrc/localrc DATABASE_BACKENDS has not been
 # initialized yet, just save the configuration selection and call back later
@@ -1259,6 +1266,7 @@
     fi
 }
 
+
 # Toggle enable/disable_service for services that must run exclusive of each other
 #  $1 The name of a variable containing a space-separated list of services
 #  $2 The name of a variable in which to store the enabled service's name
@@ -1275,6 +1283,7 @@
     return 0
 }
 
+
 # Wait for an HTTP server to start answering requests
 # wait_for_service timeout url
 function wait_for_service() {
@@ -1283,6 +1292,7 @@
     timeout $timeout sh -c "while ! http_proxy= https_proxy= curl -s $url >/dev/null; do sleep 1; done"
 }
 
+
 # Wrapper for ``yum`` to set proxy environment variables
 # Uses globals ``OFFLINE``, ``*_proxy`
 # yum_install package [package ...]
@@ -1295,8 +1305,21 @@
         yum install -y "$@"
 }
 
+
+# zypper wrapper to set arguments correctly
+# zypper_install package [package ...]
+function zypper_install() {
+    [[ "$OFFLINE" = "True" ]] && return
+    local sudo="sudo"
+    [[ "$(id -u)" = "0" ]] && sudo="env"
+    $sudo http_proxy=$http_proxy https_proxy=$https_proxy \
+        zypper --non-interactive install --auto-agree-with-licenses "$@"
+}
+
+
 # ping check
 # Uses globals ``ENABLED_SERVICES``
+# ping_check from-net ip boot-timeout expected
 function ping_check() {
     if is_service_enabled quantum; then
         _ping_check_quantum  "$1" $2 $3 $4
@@ -1333,8 +1356,10 @@
     fi
 }
 
+
 # ssh check
 
+# ssh_check net-name key-file floating-ip default-user active-timeout
 function ssh_check() {
     if is_service_enabled quantum; then
         _ssh_check_quantum  "$1" $2 $3 $4 $5
@@ -1356,17 +1381,6 @@
 }
 
 
-# zypper wrapper to set arguments correctly
-# zypper_install package [package ...]
-function zypper_install() {
-    [[ "$OFFLINE" = "True" ]] && return
-    local sudo="sudo"
-    [[ "$(id -u)" = "0" ]] && sudo="env"
-    $sudo http_proxy=$http_proxy https_proxy=$https_proxy \
-        zypper --non-interactive install --auto-agree-with-licenses "$@"
-}
-
-
 # Add a user to a group.
 # add_user_to_group user group
 function add_user_to_group() {
@@ -1396,6 +1410,7 @@
     fi
 }
 
+
 # Get the location of the $module-rootwrap executables, where module is cinder
 # or nova.
 # get_rootwrap_location module
@@ -1405,6 +1420,7 @@
     echo "$(get_python_exec_prefix)/$module-rootwrap"
 }
 
+
 # Get the path to the pip command.
 # get_pip_command
 function get_pip_command() {
@@ -1419,6 +1435,7 @@
     fi
 }
 
+
 # Path permissions sanity check
 # check_path_perm_sanity path
 function check_path_perm_sanity() {
@@ -1448,6 +1465,7 @@
     done
 }
 
+
 # Restore xtrace
 $XTRACE
 
diff --git a/lib/cinder b/lib/cinder
index 7e9c2ba..6636397 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -194,7 +194,7 @@
         iniset $CINDER_CONF lvmdriver-1 volume_backend_name LVM_iSCSI
         iniset $CINDER_CONF lvmdriver-2 volume_group $VOLUME_GROUP2
         iniset $CINDER_CONF lvmdriver-2 volume_driver cinder.volume.drivers.lvm.LVMISCSIDriver
-        iniset $CINDER_CONF lvmdriver-2 volume_backend_name LVM_iSCSI
+        iniset $CINDER_CONF lvmdriver-2 volume_backend_name LVM_iSCSI_2
     else
         iniset $CINDER_CONF DEFAULT volume_group $VOLUME_GROUP
         iniset $CINDER_CONF DEFAULT volume_name_template ${VOLUME_NAME_PREFIX}%s
diff --git a/lib/horizon b/lib/horizon
index ab11399..0cc250e 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -74,13 +74,20 @@
 }
 
 
+
 # Entry Points
 # ------------
 
 # cleanup_horizon() - Remove residual data files, anything left over from previous
 # runs that a clean run would need to clean up
 function cleanup_horizon() {
-    :
+    if [[ is_fedora && $DISTRO =~ (rhel6) ]]; then
+        # If ``/usr/bin/node`` points into ``$DEST``
+        # we installed it via ``install_nodejs``
+        if [[ $(readlink -f /usr/bin/node) =~ ($DEST) ]]; then
+            sudo rm /usr/bin/node
+        fi
+    fi
 }
 
 # configure_horizon() - Set config files, create data dirs, etc
@@ -111,7 +118,6 @@
     # Create an empty directory that apache uses as docroot
     sudo mkdir -p $HORIZON_DIR/.blackhole
 
-
     HORIZON_REQUIRE=''
     if is_ubuntu; then
         # Clean up the old config name
@@ -148,7 +154,6 @@
         s,%DEST%,$DEST,g;
         s,%HORIZON_REQUIRE%,$HORIZON_REQUIRE,g;
     \" $FILES/apache-horizon.template >/etc/$APACHE_NAME/$APACHE_CONF"
-
 }
 
 # install_horizon() - Collect source and prepare
@@ -193,6 +198,7 @@
     fi
 }
 
+
 # Restore xtrace
 $XTRACE
 
diff --git a/lib/keystone b/lib/keystone
index 6bf4d9f..2edd137 100644
--- a/lib/keystone
+++ b/lib/keystone
@@ -178,7 +178,6 @@
     cp $KEYSTONE_DIR/etc/logging.conf.sample $KEYSTONE_CONF_DIR/logging.conf
     iniset $KEYSTONE_CONF_DIR/logging.conf logger_root level "DEBUG"
     iniset $KEYSTONE_CONF_DIR/logging.conf logger_root handlers "devel,production"
-
 }
 
 # create_keystone_accounts() - Sets up common required keystone accounts
@@ -254,25 +253,6 @@
             --adminurl "$KEYSTONE_AUTH_PROTOCOL://$KEYSTONE_AUTH_HOST:$KEYSTONE_AUTH_PORT/v2.0" \
             --internalurl "$KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0"
     fi
-
-    # TODO(dtroyer): This is part of a series of changes...remove these when
-    #                complete if they are really unused
-#    KEYSTONEADMIN_ROLE=$(keystone role-create \
-#        --name KeystoneAdmin \
-#        | grep " id " | get_field 2)
-#    KEYSTONESERVICE_ROLE=$(keystone role-create \
-#        --name KeystoneServiceAdmin \
-#        | grep " id " | get_field 2)
-
-    # TODO(termie): these two might be dubious
-#    keystone user-role-add \
-#        --user_id $ADMIN_USER \
-#        --role_id $KEYSTONEADMIN_ROLE \
-#        --tenant_id $ADMIN_TENANT
-#    keystone user-role-add \
-#        --user_id $ADMIN_USER \
-#        --role_id $KEYSTONESERVICE_ROLE \
-#        --tenant_id $ADMIN_TENANT
 }
 
 # init_keystone() - Initialize databases, etc.
@@ -339,6 +319,7 @@
     screen -S $SCREEN_NAME -p key -X kill
 }
 
+
 # Restore xtrace
 $XTRACE
 
diff --git a/lib/nova b/lib/nova
index 508ed78..cac6330 100644
--- a/lib/nova
+++ b/lib/nova
@@ -300,7 +300,7 @@
             fi
 
             if is_fedora || is_suse; then
-                if is_fedora && [[  $DISTRO =~ (rhel6) || "$os_RELEASE" -le "17" ]]; then
+                if is_fedora && [[ $DISTRO =~ (rhel6) || "$os_RELEASE" -le "17" ]]; then
                     sudo bash -c "cat <<EOF >/etc/polkit-1/localauthority/50-local.d/50-libvirt-remote-access.pkla
 [libvirt Management Access]
 Identity=unix-group:$LIBVIRT_GROUP
@@ -352,7 +352,6 @@
             restart_service $LIBVIRT_DAEMON
         fi
 
-
         # Instance Storage
         # ----------------
 
@@ -494,7 +493,6 @@
         iniset_multiline $NOVA_CONF DEFAULT notification_driver "nova.openstack.common.notifier.rpc_notifier" "ceilometer.compute.nova_notifier"
     fi
 
-
     # Provide some transition from ``EXTRA_FLAGS`` to ``EXTRA_OPTS``
     if [[ -z "$EXTRA_OPTS" && -n "$EXTRA_FLAGS" ]]; then
         EXTRA_OPTS=$EXTRA_FLAGS
diff --git a/lib/quantum b/lib/quantum
index d85c648..1a826f8 100644
--- a/lib/quantum
+++ b/lib/quantum
@@ -52,6 +52,10 @@
 # Quantum.
 #
 # With Quantum networking the NETWORK_MANAGER variable is ignored.
+#
+# To enable specific configuration options for either the Open vSwitch or
+# LinuxBridge plugin, please see the top level README file under the
+# Quantum section.
 
 # Save trace setting
 XTRACE=$(set +o | grep xtrace)
@@ -112,18 +116,18 @@
     # The following variables control the Quantum openvswitch and
     # linuxbridge plugins' allocation of tenant networks and
     # availability of provider networks. If these are not configured
-    # in localrc, tenant networks will be local to the host (with no
+    # in ``localrc``, tenant networks will be local to the host (with no
     # remote connectivity), and no physical resources will be
     # available for the allocation of provider networks.
 
     # To use GRE tunnels for tenant networks, set to True in
-    # localrc. GRE tunnels are only supported by the openvswitch
+    # ``localrc``. GRE tunnels are only supported by the openvswitch
     # plugin, and currently only on Ubuntu.
     ENABLE_TENANT_TUNNELS=${ENABLE_TENANT_TUNNELS:-False}
 
     # If using GRE tunnels for tenant networks, specify the range of
     # tunnel IDs from which tenant networks are allocated. Can be
-    # overriden in localrc in necesssary.
+    # overriden in ``localrc`` in necesssary.
     TENANT_TUNNEL_RANGES=${TENANT_TUNNEL_RANGE:-1:1000}
 
     # To use VLANs for tenant networks, set to True in localrc. VLANs
@@ -131,7 +135,7 @@
     # requiring additional configuration described below.
     ENABLE_TENANT_VLANS=${ENABLE_TENANT_VLANS:-False}
 
-    # If using VLANs for tenant networks, set in localrc to specify
+    # If using VLANs for tenant networks, set in ``localrc`` to specify
     # the range of VLAN VIDs from which tenant networks are
     # allocated. An external network switch must be configured to
     # trunk these VLANs between hosts for multi-host connectivity.
@@ -140,16 +144,16 @@
     TENANT_VLAN_RANGE=${TENANT_VLAN_RANGE:-}
 
     # If using VLANs for tenant networks, or if using flat or VLAN
-    # provider networks, set in localrc to the name of the physical
-    # network, and also configure OVS_PHYSICAL_BRIDGE for the
-    # openvswitch agent or LB_PHYSICAL_INTERFACE for the linuxbridge
+    # provider networks, set in ``localrc`` to the name of the physical
+    # network, and also configure ``OVS_PHYSICAL_BRIDGE`` for the
+    # openvswitch agent or ``LB_PHYSICAL_INTERFACE`` for the linuxbridge
     # agent, as described below.
     #
     # Example: ``PHYSICAL_NETWORK=default``
     PHYSICAL_NETWORK=${PHYSICAL_NETWORK:-}
 
     # With the openvswitch plugin, if using VLANs for tenant networks,
-    # or if using flat or VLAN provider networks, set in localrc to
+    # or if using flat or VLAN provider networks, set in ``localrc`` to
     # the name of the OVS bridge to use for the physical network. The
     # bridge will be created if it does not already exist, but a
     # physical interface must be manually added to the bridge as a
@@ -159,28 +163,29 @@
     OVS_PHYSICAL_BRIDGE=${OVS_PHYSICAL_BRIDGE:-}
 
     # With the linuxbridge plugin, if using VLANs for tenant networks,
-    # or if using flat or VLAN provider networks, set in localrc to
+    # or if using flat or VLAN provider networks, set in ``localrc`` to
     # the name of the network interface to use for the physical
     # network.
     #
     # Example: ``LB_PHYSICAL_INTERFACE=eth1``
     LB_PHYSICAL_INTERFACE=${LB_PHYSICAL_INTERFACE:-}
 
-    # With the openvswitch plugin, set to True in localrc to enable
+    # With the openvswitch plugin, set to True in ``localrc`` to enable
     # provider GRE tunnels when ``ENABLE_TENANT_TUNNELS`` is False.
     #
     # Example: ``OVS_ENABLE_TUNNELING=True``
     OVS_ENABLE_TUNNELING=${OVS_ENABLE_TUNNELING:-$ENABLE_TENANT_TUNNELS}
 fi
 
-
 # Quantum plugin specific functions
 # ---------------------------------
-# Please refer to lib/quantum_plugins/README.md for details.
+
+# Please refer to ``lib/quantum_plugins/README.md`` for details.
 source $TOP_DIR/lib/quantum_plugins/$Q_PLUGIN
 
 # Agent loadbalancer service plugin functions
 # -------------------------------------------
+
 # Hardcoding for 1 service plugin for now
 source $TOP_DIR/lib/quantum_plugins/services/agent_loadbalancer
 
@@ -191,7 +196,6 @@
     Q_USE_SECGROUP=False
 fi
 
-
 # Functions
 # ---------
 
@@ -423,7 +427,7 @@
 
 # _configure_quantum_common()
 # Set common config for all quantum server and agents.
-# This MUST be called before other _configure_quantum_* functions.
+# This MUST be called before other ``_configure_quantum_*`` functions.
 function _configure_quantum_common() {
     # Put config files in ``QUANTUM_CONF_DIR`` for everyone to find
     if [[ ! -d $QUANTUM_CONF_DIR ]]; then
@@ -433,11 +437,11 @@
 
     cp $QUANTUM_DIR/etc/quantum.conf $QUANTUM_CONF
 
-    # Set plugin-specific variables Q_DB_NAME, Q_PLUGIN_CLASS.
-    # For main plugin config file, set Q_PLUGIN_CONF_PATH, Q_PLUGIN_CONF_FILENAME.
-    # For addition plugin config files, set Q_PLUGIN_EXTRA_CONF_PATH,
-    # Q_PLUGIN_EXTRA_CONF_FILES.  For example:
-    #    Q_PLUGIN_EXTRA_CONF_FILES=(file1, file2)
+    # Set plugin-specific variables ``Q_DB_NAME``, ``Q_PLUGIN_CLASS``.
+    # For main plugin config file, set ``Q_PLUGIN_CONF_PATH``, ``Q_PLUGIN_CONF_FILENAME``.
+    # For addition plugin config files, set ``Q_PLUGIN_EXTRA_CONF_PATH``,
+    # ``Q_PLUGIN_EXTRA_CONF_FILES``.  For example:
+    #    ``Q_PLUGIN_EXTRA_CONF_FILES=(file1, file2)``
     quantum_plugin_configure_common
 
     if [[ $Q_PLUGIN_CONF_PATH == '' || $Q_PLUGIN_CONF_FILENAME == '' || $Q_PLUGIN_CLASS == '' ]]; then
@@ -543,8 +547,7 @@
     _quantum_setup_keystone $Q_META_CONF_FILE DEFAULT set_auth_url
 }
 
-function _configure_quantum_lbaas()
-{
+function _configure_quantum_lbaas() {
     quantum_agent_lbaas_install_agent_packages
     quantum_agent_lbaas_configure_common
     quantum_agent_lbaas_configure_agent
@@ -606,17 +609,17 @@
         return
     fi
     # Deploy new rootwrap filters files (owned by root).
-    # Wipe any existing rootwrap.d files first
+    # Wipe any existing ``rootwrap.d`` files first
     Q_CONF_ROOTWRAP_D=$QUANTUM_CONF_DIR/rootwrap.d
     if [[ -d $Q_CONF_ROOTWRAP_D ]]; then
         sudo rm -rf $Q_CONF_ROOTWRAP_D
     fi
-    # Deploy filters to $QUANTUM_CONF_DIR/rootwrap.d
+    # Deploy filters to ``$QUANTUM_CONF_DIR/rootwrap.d``
     mkdir -p -m 755 $Q_CONF_ROOTWRAP_D
     cp -pr $QUANTUM_DIR/etc/quantum/rootwrap.d/* $Q_CONF_ROOTWRAP_D/
     sudo chown -R root:root $Q_CONF_ROOTWRAP_D
     sudo chmod 644 $Q_CONF_ROOTWRAP_D/*
-    # Set up rootwrap.conf, pointing to $QUANTUM_CONF_DIR/rootwrap.d
+    # Set up ``rootwrap.conf``, pointing to ``$QUANTUM_CONF_DIR/rootwrap.d``
     # location moved in newer versions, prefer new location
     if test -r $QUANTUM_DIR/etc/quantum/rootwrap.conf; then
       sudo cp -p $QUANTUM_DIR/etc/quantum/rootwrap.conf $Q_RR_CONF_FILE
@@ -626,7 +629,7 @@
     sudo sed -e "s:^filters_path=.*$:filters_path=$Q_CONF_ROOTWRAP_D:" -i $Q_RR_CONF_FILE
     sudo chown root:root $Q_RR_CONF_FILE
     sudo chmod 0644 $Q_RR_CONF_FILE
-    # Specify rootwrap.conf as first parameter to quantum-rootwrap
+    # Specify ``rootwrap.conf`` as first parameter to quantum-rootwrap
     ROOTWRAP_SUDOER_CMD="$QUANTUM_ROOTWRAP $Q_RR_CONF_FILE *"
 
     # Set up the rootwrap sudoers for quantum
@@ -743,7 +746,8 @@
 
 # Quantum 3rd party programs
 #---------------------------
-# please refer to lib/quantum_thirdparty/README.md for details
+
+# please refer to ``lib/quantum_thirdparty/README.md`` for details
 QUANTUM_THIRD_PARTIES=""
 for f in $TOP_DIR/lib/quantum_thirdparty/*; do
      third_party=$(basename $f)
diff --git a/lib/quantum_plugins/linuxbridge b/lib/quantum_plugins/linuxbridge
index 71832f1..dffa32b 100644
--- a/lib/quantum_plugins/linuxbridge
+++ b/lib/quantum_plugins/linuxbridge
@@ -35,6 +35,14 @@
     else
         iniset /$Q_PLUGIN_CONF_FILE SECURITYGROUP firewall_driver quantum.agent.firewall.NoopFirewallDriver
     fi
+
+    # Define extra "LINUX_BRIDGE" configuration options when q-svc is configured by defining
+    # the array ``Q_SRV_EXTRA_OPTS``.
+    # For Example: ``Q_SRV_EXTRA_OPTS=(foo=true bar=2)``
+    for I in "${Q_SRV_EXTRA_OPTS[@]}"; do
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset /$Q_PLUGIN_CONF_FILE LINUX_BRIDGE ${I/=/ }
+    done
 }
 
 function has_quantum_plugin_security_group() {
diff --git a/lib/quantum_plugins/linuxbridge_agent b/lib/quantum_plugins/linuxbridge_agent
index 1e83275..7855cd0 100644
--- a/lib/quantum_plugins/linuxbridge_agent
+++ b/lib/quantum_plugins/linuxbridge_agent
@@ -47,6 +47,20 @@
         iniset /$Q_PLUGIN_CONF_FILE SECURITYGROUP firewall_driver quantum.agent.firewall.NoopFirewallDriver
     fi
     AGENT_BINARY="$QUANTUM_DIR/bin/quantum-linuxbridge-agent"
+    # Define extra "AGENT" configuration options when q-agt is configured by defining
+    # the array ``Q_AGENT_EXTRA_AGENT_OPTS``.
+    # For Example: ``Q_AGENT_EXTRA_AGENT_OPTS=(foo=true bar=2)``
+    for I in "${Q_AGENT_EXTRA_AGENT_OPTS[@]}"; do
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset /$Q_PLUGIN_CONF_FILE AGENT ${I/=/ }
+    done
+    # Define extra "LINUX_BRIDGE" configuration options when q-agt is configured by defining
+    # the array ``Q_AGENT_EXTRA_SRV_OPTS``.
+    # For Example: ``Q_AGENT_EXTRA_SRV_OPTS=(foo=true bar=2)``
+    for I in "${Q_AGENT_EXTRA_SRV_OPTS[@]}"; do
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset /$Q_PLUGIN_CONF_FILE LINUX_BRIDGE ${I/=/ }
+    done
 }
 
 function quantum_plugin_setup_interface_driver() {
diff --git a/lib/quantum_plugins/openvswitch b/lib/quantum_plugins/openvswitch
index cd29c19..e53db8a 100644
--- a/lib/quantum_plugins/openvswitch
+++ b/lib/quantum_plugins/openvswitch
@@ -42,6 +42,14 @@
     fi
 
     _quantum_ovs_base_configure_firewall_driver
+
+    # Define extra "OVS" configuration options when q-svc is configured by defining
+    # the array ``Q_SRV_EXTRA_OPTS``.
+    # For Example: ``Q_SRV_EXTRA_OPTS=(foo=true bar=2)``
+    for I in "${Q_SRV_EXTRA_OPTS[@]}"; do
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset /$Q_PLUGIN_CONF_FILE OVS ${I/=/ }
+    done
 }
 
 function has_quantum_plugin_security_group() {
diff --git a/lib/quantum_plugins/openvswitch_agent b/lib/quantum_plugins/openvswitch_agent
index 87f5e97..ee761ed 100644
--- a/lib/quantum_plugins/openvswitch_agent
+++ b/lib/quantum_plugins/openvswitch_agent
@@ -102,6 +102,20 @@
         # Set root wrap
         iniset "/$Q_PLUGIN_CONF_FILE.domU" AGENT root_helper "$Q_RR_COMMAND"
     fi
+    # Define extra "AGENT" configuration options when q-agt is configured by defining
+    # defining the array ``Q_AGENT_EXTRA_AGENT_OPTS``.
+    # For Example: ``Q_AGENT_EXTRA_AGENT_OPTS=(foo=true bar=2)``
+    for I in "${Q_AGENT_EXTRA_AGENT_OPTS[@]}"; do
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset /$Q_PLUGIN_CONF_FILE AGENT ${I/=/ }
+    done
+    # Define extra "OVS" configuration options when q-agt is configured by defining
+    # defining the array ``Q_AGENT_EXTRA_SRV_OPTS``.
+    # For Example: ``Q_AGENT_EXTRA_SRV_OPTS=(foo=true bar=2)``
+    for I in "${Q_AGENT_EXTRA_SRV_OPTS[@]}"; do
+        # Replace the first '=' with ' ' for iniset syntax
+        iniset /$Q_PLUGIN_CONF_FILE OVS ${I/=/ }
+    done
 }
 
 function quantum_plugin_setup_interface_driver() {
diff --git a/lib/tempest b/lib/tempest
index a259ee9..8018166 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -23,6 +23,7 @@
 # ``USE_BLOCK_MIGRATION_FOR_LIVE_MIGRATION``
 # ``DEFAULT_INSTANCE_TYPE``
 # ``DEFAULT_INSTANCE_USER``
+# ``CINDER_MULTI_LVM_BACKEND``
 # ``stack.sh`` calls the entry points in this order:
 #
 # install_tempest
@@ -44,7 +45,7 @@
 
 NOVA_SOURCE_DIR=$DEST/nova
 
-BUILD_INTERVAL=3
+BUILD_INTERVAL=1
 BUILD_TIMEOUT=400
 
 
@@ -234,11 +235,10 @@
     iniset $TEMPEST_CONF whitebox path_to_private_key $TEMPEST_DIR/id_rsa
     iniset $TEMPEST_CONF whitebox db_uri $BASE_SQL_CONN/nova
 
-
-    # compute admin
+    # Compute admin
     iniset $TEMPEST_CONF "compute-admin" password "$password" # DEPRECATED
 
-    # network
+    # Network
     if is_service_enabled quantum; then
         iniset $TEMPEST_CONF network quantum_available "True"
     fi
@@ -247,7 +247,7 @@
     iniset $TEMPEST_CONF network public_network_id "$public_network_id"
     iniset $TEMPEST_CONF network public_router_id "$public_router_id"
 
-    #boto
+    # boto
     iniset $TEMPEST_CONF boto ec2_url "http://$SERVICE_HOST:8773/services/Cloud"
     iniset $TEMPEST_CONF boto s3_url "http://$SERVICE_HOST:${S3_SERVICE_PORT:-3333}"
     iniset $TEMPEST_CONF boto s3_materials_path "$BOTO_MATERIALS_PATH"
@@ -255,11 +255,19 @@
     iniset $TEMPEST_CONF boto http_socket_timeout 30
     iniset $TEMPEST_CONF boto ssh_user ${DEFAULT_INSTANCE_USER:-cirros}
 
-    # orchestration
+    # Orchestration
     if is_service_enabled heat; then
         iniset $TEMPEST_CONF orchestration heat_available "True"
     fi
 
+    # Volume
+    CINDER_MULTI_LVM_BACKEND=$(trueorfalse False $CINDER_MULTI_LVM_BACKEND)
+    if [ $CINDER_MULTI_LVM_BACKEND == "True "]; then
+        iniset $TEMPEST_CONF volume multi_backend_enabled "True"
+        iniset $TEMPEST_CONF volume backend1_name "LVM_iSCSI"
+        iniset $TEMPEST_CONF volume backend2_name "LVM_iSCSI_2"
+    fi
+
     echo "Created tempest configuration file:"
     cat $TEMPEST_CONF
 
diff --git a/stack.sh b/stack.sh
index 1e61a3f..24a3d5f 100755
--- a/stack.sh
+++ b/stack.sh
@@ -3,7 +3,7 @@
 # ``stack.sh`` is an opinionated OpenStack developer installation.  It
 # installs and configures various combinations of **Ceilometer**, **Cinder**,
 # **Glance**, **Heat**, **Horizon**, **Keystone**, **Nova**, **Quantum**
-# and **Swift**
+# and **Swift**.
 
 # This script allows you to specify configuration options of what git
 # repositories to use, enabled services, network configuration and various
@@ -12,9 +12,11 @@
 # developer install.
 
 # To keep this script simple we assume you are running on a recent **Ubuntu**
-# (12.04 Precise or newer) or **Fedora** (F16 or newer) machine.  It
-# should work in a VM or physical server.  Additionally we put the list of
-# ``apt`` and ``rpm`` dependencies and other configuration files in this repo.
+# (12.04 Precise or newer) or **Fedora** (F16 or newer) machine.  (It may work
+# on other platforms but support for those platforms is left to those who added
+# them to DevStack.)  It should work in a VM or physical server.  Additionally
+# we maintain a list of ``apt`` and ``rpm`` dependencies and other configuration
+# files in this repo.
 
 # Learn more and get the most recent version at http://devstack.org
 
@@ -33,55 +35,20 @@
 GetDistro
 
 
-# Configure non-default repos
-# ===========================
-
-# Repo configuration needs to occur before package installation.
-
-# Some dependencies are not available in Debian Wheezy official
-# repositories. However, it's possible to run OpenStack from gplhost
-# repository.
-if [[ "$os_VENDOR" =~ (Debian) ]]; then
-    echo 'deb http://archive.gplhost.com/debian grizzly main' | sudo tee /etc/apt/sources.list.d/gplhost_wheezy-backports.list
-    echo 'deb http://archive.gplhost.com/debian grizzly-backports main' | sudo tee -a /etc/apt/sources.list.d/gplhost_wheezy-backports.list
-    apt_get update
-    apt_get install --force-yes gplhost-archive-keyring
-fi
-
-# Installing Open vSwitch on RHEL6 requires enabling the RDO repo.
-RHEL6_RDO_REPO_RPM=${RHEL6_RDO_REPO_RPM:-"http://rdo.fedorapeople.org/openstack/openstack-grizzly/rdo-release-grizzly-3.noarch.rpm"}
-RHEL6_RDO_REPO_ID=${RHEL6_RDO_REPO_ID:-"openstack-grizzly"}
-# RHEL6 requires EPEL for many Open Stack dependencies
-RHEL6_EPEL_RPM=${RHEL6_EPEL_RPM:-"http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm"}
-
-if [[ is_fedora && $DISTRO =~ (rhel6) ]]; then
-
-    if ! yum repolist enabled $RHEL6_RDO_REPO_ID | grep -q $RHEL6_RDO_REPO_ID; then
-        echo "RDO repo not detected; installing"
-        yum_install $RHEL6_RDO_REPO_RPM || \
-            die $LINENO "Error installing RDO repo, cannot continue"
-    fi
-
-    if ! yum repolist enabled epel | grep -q 'epel'; then
-        echo "EPEL not detected; installing"
-        yum_install ${RHEL6_EPEL_RPM} || \
-            die $LINENO "Error installing EPEL repo, cannot continue"
-    fi
-
-fi
-
 # Global Settings
 # ===============
 
-# ``stack.sh`` is customizable through setting environment variables.  If you
-# want to override a setting you can set and export it::
+# ``stack.sh`` is customizable by setting environment variables.  Override a
+# default setting via export::
 #
 #     export DATABASE_PASSWORD=anothersecret
 #     ./stack.sh
 #
-# You can also pass options on a single line ``DATABASE_PASSWORD=simple ./stack.sh``
+# or by setting the variable on the command line::
 #
-# Additionally, you can put any local variables into a ``localrc`` file::
+#     DATABASE_PASSWORD=simple ./stack.sh
+#
+# Persistent variables can be placed in a ``localrc`` file::
 #
 #     DATABASE_PASSWORD=anothersecret
 #     DATABASE_USER=hellaroot
@@ -166,6 +133,41 @@
 VERBOSE=$(trueorfalse True $VERBOSE)
 
 
+# Additional repos
+# ================
+
+# Some distros need to add repos beyond the defaults provided by the vendor
+# to pick up required packages.
+
+# The Debian Wheezy official repositories do not contain all required packages,
+# add gplhost repository.
+if [[ "$os_VENDOR" =~ (Debian) ]]; then
+    echo 'deb http://archive.gplhost.com/debian grizzly main' | sudo tee /etc/apt/sources.list.d/gplhost_wheezy-backports.list
+    echo 'deb http://archive.gplhost.com/debian grizzly-backports main' | sudo tee -a /etc/apt/sources.list.d/gplhost_wheezy-backports.list
+    apt_get update
+    apt_get install --force-yes gplhost-archive-keyring
+fi
+
+if [[ is_fedora && $DISTRO =~ (rhel6) ]]; then
+    # Installing Open vSwitch on RHEL6 requires enabling the RDO repo.
+    RHEL6_RDO_REPO_RPM=${RHEL6_RDO_REPO_RPM:-"http://rdo.fedorapeople.org/openstack/openstack-grizzly/rdo-release-grizzly-3.noarch.rpm"}
+    RHEL6_RDO_REPO_ID=${RHEL6_RDO_REPO_ID:-"openstack-grizzly"}
+    if ! yum repolist enabled $RHEL6_RDO_REPO_ID | grep -q $RHEL6_RDO_REPO_ID; then
+        echo "RDO repo not detected; installing"
+        yum_install $RHEL6_RDO_REPO_RPM || \
+            die $LINENO "Error installing RDO repo, cannot continue"
+    fi
+
+    # RHEL6 requires EPEL for many Open Stack dependencies
+    RHEL6_EPEL_RPM=${RHEL6_EPEL_RPM:-"http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm"}
+    if ! yum repolist enabled epel | grep -q 'epel'; then
+        echo "EPEL not detected; installing"
+        yum_install ${RHEL6_EPEL_RPM} || \
+            die $LINENO "Error installing EPEL repo, cannot continue"
+    fi
+fi
+
+
 # root Access
 # -----------
 
@@ -296,7 +298,7 @@
 # Configure Projects
 # ==================
 
-# Get project function libraries
+# Source project function libraries
 source $TOP_DIR/lib/tls
 source $TOP_DIR/lib/horizon
 source $TOP_DIR/lib/keystone
@@ -310,7 +312,7 @@
 source $TOP_DIR/lib/baremetal
 source $TOP_DIR/lib/ldap
 
-# Set the destination directories for OpenStack projects
+# Set the destination directories for other OpenStack projects
 OPENSTACKCLIENT_DIR=$DEST/python-openstackclient
 PBR_DIR=$DEST/pbr
 
@@ -565,6 +567,7 @@
 # an error.  It is also useful for following along as the install occurs.
 set -o xtrace
 
+
 # Install Packages
 # ================
 
@@ -585,61 +588,51 @@
     install_quantum_agent_packages
 fi
 
-#
+
 # System-specific preconfigure
 # ============================
 
 if [[ is_fedora && $DISTRO =~ (rhel6) ]]; then
-    # Avoid having to configure selinux to allow things like httpd to
-    # access horizion files or run binaries like nodejs (LP#1175444)
+    # Disable selinux to avoid configuring to allow Apache access
+    # to Horizon files or run nodejs (LP#1175444)
     if selinuxenabled; then
         sudo setenforce 0
     fi
 
-    # An old version (2.0.1) of python-crypto is probably installed on
-    # a fresh system, via the dependency chain
-    # cas->python-paramiko->python-crypto (related to anaconda).
-    # Unfortunately, "pip uninstall pycrypto" will remove the
-    # .egg-info file for this rpm-installed version, but leave most of
-    # the actual library files behind in /usr/lib64/python2.6/Crypto.
-    # When later "pip install pycrypto" happens, the built library
-    # will be installed over these existing files; the result is a
-    # useless mess of old, rpm-packaged files and pip-installed files.
-    # Unsurprisingly, the end result is it doesn't work.  Thus we have
-    # to get rid of it now so that any packages that pip-install
-    # pycrypto get a "clean slate".
-    # (note, we have to be careful about other RPM packages specified
-    # pulling in python-crypto as well.  That's why RHEL6 doesn't
-    # install python-paramiko packages for example...)
+    # An old version of ``python-crypto`` (2.0.1) may be installed on a
+    # fresh system via Anaconda and the dependency chain
+    # ``cas`` -> ``python-paramiko`` -> ``python-crypto``.
+    # ``pip uninstall pycrypto`` will remove the packaged ``.egg-info`` file
+    # but leave most of the actual library files behind in ``/usr/lib64/python2.6/Crypto``.
+    # Later ``pip install pycrypto`` will install over the packaged files resulting
+    # in a useless mess of old, rpm-packaged files and pip-installed files.
+    # Remove the package so that ``pip install python-crypto`` installs cleanly.
+    # Note: other RPM packages may require ``python-crypto`` as well.  For example,
+    # RHEL6 does not install ``python-paramiko packages``.
     uninstall_package python-crypto
 
-    # A similar thing happens for python-lxml (a dependency of
-    # ipa-client, an auditing thing we don't care about).  We have the
-    # build-dependencies the lxml pip-install will need (gcc,
-    # libxml2-dev & libxslt-dev) in the "general" rpm lists
+    # A similar situation occurs with ``python-lxml``, which is required by
+    # ``ipa-client``, an auditing package we don't care about.  The
+    # build-dependencies needed for ``pip install lxml`` (``gcc``,
+    # ``libxml2-dev`` and ``libxslt-dev``) are present in ``files/rpms/general``.
     uninstall_package python-lxml
 
-    # If the dbus rpm was installed by the devstack rpm dependencies
-    # then you may hit a bug where the uuid isn't generated because
-    # the service was never started (PR#598200), causing issues for
-    # Nova stopping later on complaining that
-    # '/var/lib/dbus/machine-id' doesn't exist.
+    # If the ``dbus`` package was installed by DevStack dependencies the
+    # uuid may not be generated because the service was never started (PR#598200),
+    # causing Nova to stop later on complaining that ``/var/lib/dbus/machine-id``
+    # does not exist.
     sudo service messagebus restart
 
-    # In setup.py, a "setup_requires" package is supposed to
-    # transient.  However there is a bug with rhel6 distribute where
-    # setup_requires packages can register entry points that aren't
-    # cleared out properly after the setup-phase; the end result is
-    # installation failures (bz#924038).  Thus we pre-install the
-    # problem package here; this way the setup_requires dependency is
-    # already satisfied and it will not need to be installed
-    # transiently, meaning we avoid the issue of it not being cleaned
-    # out properly.  Note we do this before the track-depends below.
+    # ``setup.py`` contains a ``setup_requires`` package that is supposed
+    # to be transient.  However, RHEL6 distribute has a bug where
+    # ``setup_requires`` registers entry points that are not cleaned
+    # out properly after the setup-phase resulting in installation failures
+    # (bz#924038).  Pre-install the problem package so the ``setup_requires``
+    # dependency is satisfied and it will not be installed transiently.
+    # Note we do this before the track-depends below.
     pip_install hgtools
 
-    # The version of python-nose in the RHEL6 repo is incompatible
-    # with Tempest.  As a workaround:
-
+    # RHEL6's version of ``python-nose`` is incompatible with Tempest.
     # Install nose 1.1 (Tempest-compatible) from EPEL
     install_package python-nose1.1
     # Add a symlink for the new nosetests to allow tox for Tempest to
@@ -850,10 +843,10 @@
 init_service_check
 
 
-# Kick off Sysstat
-# ------------------------
-# run sysstat if it is enabled, this has to be early as daemon
-# startup is one of the things to track.
+# Sysstat
+# -------
+
+# If enabled, systat has to start early to track OpenStack service startup.
 if is_service_enabled sysstat;then
     if [[ -n ${SCREEN_LOGDIR} ]]; then
         screen_it sysstat "sar -o $SCREEN_LOGDIR/$SYSSTAT_FILE $SYSSTAT_INTERVAL"
@@ -967,7 +960,7 @@
     rm -rf ${NOVA_STATE_PATH}/networks
     sudo mkdir -p ${NOVA_STATE_PATH}/networks
     sudo chown -R ${USER} ${NOVA_STATE_PATH}/networks
-    # Force IP forwarding on, just on case
+    # Force IP forwarding on, just in case
     sudo sysctl -w net.ipv4.ip_forward=1
 fi
 
@@ -1018,6 +1011,7 @@
         XEN_FIREWALL_DRIVER=${XEN_FIREWALL_DRIVER:-"nova.virt.firewall.IptablesFirewallDriver"}
         iniset $NOVA_CONF DEFAULT firewall_driver "$XEN_FIREWALL_DRIVER"
 
+
     # OpenVZ
     # ------
 
@@ -1028,6 +1022,7 @@
         LIBVIRT_FIREWALL_DRIVER=${LIBVIRT_FIREWALL_DRIVER:-"nova.virt.libvirt.firewall.IptablesFirewallDriver"}
         iniset $NOVA_CONF DEFAULT firewall_driver "$LIBVIRT_FIREWALL_DRIVER"
 
+
     # Bare Metal
     # ----------
 
@@ -1050,6 +1045,7 @@
            iniset $NOVA_CONF baremetal ${I/=/ }
         done
 
+
    # PowerVM
    # -------
 
@@ -1069,8 +1065,9 @@
         iniset $NOVA_CONF DEFAULT powervm_img_remote_path $POWERVM_IMG_REMOTE_PATH
         iniset $NOVA_CONF DEFAULT powervm_img_local_path $POWERVM_IMG_LOCAL_PATH
 
+
     # vSphere API
-    # -------
+    # -----------
 
     elif [ "$VIRT_DRIVER" = 'vsphere' ]; then
         echo_summary "Using VMware vCenter driver"
@@ -1081,8 +1078,9 @@
         iniset $NOVA_CONF DEFAULT vmwareapi_host_password "$VMWAREAPI_PASSWORD"
         iniset $NOVA_CONF DEFAULT vmwareapi_cluster_name "$VMWAREAPI_CLUSTER"
 
+
     # fake
-    # -----
+    # ----
 
     elif [ "$VIRT_DRIVER" = 'fake' ]; then
         echo_summary "Using fake Virt driver"
@@ -1102,8 +1100,8 @@
         iniset $NOVA_CONF DEFAULT scheduler_default_filters "RetryFilter,AvailabilityZoneFilter,ComputeFilter,ComputeCapabilitiesFilter,ImagePropertiesFilter"
 
 
-    # Default
-    # -------
+    # Default libvirt
+    # ---------------
 
     else
         echo_summary "Using libvirt virtualization driver"
@@ -1296,7 +1294,6 @@
     screen_it baremetal "nova-baremetal-deploy-helper"
 fi
 
-
 # Save some values we generated for later use
 CURRENT_RUN_TIME=$(date "+$TIMESTAMP_FORMAT")
 echo "# $CURRENT_RUN_TIME" >$TOP_DIR/.stackenv
diff --git a/stackrc b/stackrc
index 2ac564c..ef39710 100644
--- a/stackrc
+++ b/stackrc
@@ -73,10 +73,58 @@
 CINDERCLIENT_REPO=${CINDERCLIENT_REPO:-${GIT_BASE}/openstack/python-cinderclient.git}
 CINDERCLIENT_BRANCH=${CINDERCLIENT_BRANCH:-master}
 
+# image catalog service
+GLANCE_REPO=${GLANCE_REPO:-${GIT_BASE}/openstack/glance.git}
+GLANCE_BRANCH=${GLANCE_BRANCH:-master}
+
+# python glance client library
+GLANCECLIENT_REPO=${GLANCECLIENT_REPO:-${GIT_BASE}/openstack/python-glanceclient.git}
+GLANCECLIENT_BRANCH=${GLANCECLIENT_BRANCH:-master}
+
+# heat service
+HEAT_REPO=${HEAT_REPO:-${GIT_BASE}/openstack/heat.git}
+HEAT_BRANCH=${HEAT_BRANCH:-master}
+
+# python heat client library
+HEATCLIENT_REPO=${HEATCLIENT_REPO:-${GIT_BASE}/openstack/python-heatclient.git}
+HEATCLIENT_BRANCH=${HEATCLIENT_BRANCH:-master}
+
+# django powered web control panel for openstack
+HORIZON_REPO=${HORIZON_REPO:-${GIT_BASE}/openstack/horizon.git}
+HORIZON_BRANCH=${HORIZON_BRANCH:-master}
+
+# unified auth system (manages accounts/tokens)
+KEYSTONE_REPO=${KEYSTONE_REPO:-${GIT_BASE}/openstack/keystone.git}
+KEYSTONE_BRANCH=${KEYSTONE_BRANCH:-master}
+
+# python keystone client library to nova that horizon uses
+KEYSTONECLIENT_REPO=${KEYSTONECLIENT_REPO:-${GIT_BASE}/openstack/python-keystoneclient.git}
+KEYSTONECLIENT_BRANCH=${KEYSTONECLIENT_BRANCH:-master}
+
 # compute service
 NOVA_REPO=${NOVA_REPO:-${GIT_BASE}/openstack/nova.git}
 NOVA_BRANCH=${NOVA_BRANCH:-master}
 
+# python client library to nova that horizon (and others) use
+NOVACLIENT_REPO=${NOVACLIENT_REPO:-${GIT_BASE}/openstack/python-novaclient.git}
+NOVACLIENT_BRANCH=${NOVACLIENT_BRANCH:-master}
+
+# consolidated openstack python client
+OPENSTACKCLIENT_REPO=${OPENSTACKCLIENT_REPO:-${GIT_BASE}/openstack/python-openstackclient.git}
+OPENSTACKCLIENT_BRANCH=${OPENSTACKCLIENT_BRANCH:-master}
+
+# pbr drives the setuptools configs
+PBR_REPO=${PBR_REPO:-${GIT_BASE}/openstack-dev/pbr.git}
+PBR_BRANCH=${PBR_BRANCH:-master}
+
+# quantum service
+QUANTUM_REPO=${QUANTUM_REPO:-${GIT_BASE}/openstack/quantum.git}
+QUANTUM_BRANCH=${QUANTUM_BRANCH:-master}
+
+# quantum client
+QUANTUMCLIENT_REPO=${QUANTUMCLIENT_REPO:-${GIT_BASE}/openstack/python-quantumclient.git}
+QUANTUMCLIENT_BRANCH=${QUANTUMCLIENT_BRANCH:-master}
+
 # storage service
 SWIFT_REPO=${SWIFT_REPO:-${GIT_BASE}/openstack/swift.git}
 SWIFT_BRANCH=${SWIFT_BRANCH:-master}
@@ -87,65 +135,10 @@
 SWIFTCLIENT_REPO=${SWIFTCLIENT_REPO:-${GIT_BASE}/openstack/python-swiftclient.git}
 SWIFTCLIENT_BRANCH=${SWIFTCLIENT_BRANCH:-master}
 
-# image catalog service
-GLANCE_REPO=${GLANCE_REPO:-${GIT_BASE}/openstack/glance.git}
-GLANCE_BRANCH=${GLANCE_BRANCH:-master}
-
-# python glance client library
-GLANCECLIENT_REPO=${GLANCECLIENT_REPO:-${GIT_BASE}/openstack/python-glanceclient.git}
-GLANCECLIENT_BRANCH=${GLANCECLIENT_BRANCH:-master}
-
-# unified auth system (manages accounts/tokens)
-KEYSTONE_REPO=${KEYSTONE_REPO:-${GIT_BASE}/openstack/keystone.git}
-KEYSTONE_BRANCH=${KEYSTONE_BRANCH:-master}
-
-# a websockets/html5 or flash powered VNC console for vm instances
-NOVNC_REPO=${NOVNC_REPO:-${GIT_BASE}/kanaka/noVNC.git}
-NOVNC_BRANCH=${NOVNC_BRANCH:-master}
-
-# a websockets/html5 or flash powered SPICE console for vm instances
-SPICE_REPO=${SPICE_REPO:-http://anongit.freedesktop.org/git/spice/spice-html5.git}
-SPICE_BRANCH=${SPICE_BRANCH:-master}
-
-# django powered web control panel for openstack
-HORIZON_REPO=${HORIZON_REPO:-${GIT_BASE}/openstack/horizon.git}
-HORIZON_BRANCH=${HORIZON_BRANCH:-master}
-
-# python client library to nova that horizon (and others) use
-NOVACLIENT_REPO=${NOVACLIENT_REPO:-${GIT_BASE}/openstack/python-novaclient.git}
-NOVACLIENT_BRANCH=${NOVACLIENT_BRANCH:-master}
-
-# consolidated openstack python client
-OPENSTACKCLIENT_REPO=${OPENSTACKCLIENT_REPO:-${GIT_BASE}/openstack/python-openstackclient.git}
-OPENSTACKCLIENT_BRANCH=${OPENSTACKCLIENT_BRANCH:-master}
-
-# python keystone client library to nova that horizon uses
-KEYSTONECLIENT_REPO=${KEYSTONECLIENT_REPO:-${GIT_BASE}/openstack/python-keystoneclient.git}
-KEYSTONECLIENT_BRANCH=${KEYSTONECLIENT_BRANCH:-master}
-
-# quantum service
-QUANTUM_REPO=${QUANTUM_REPO:-${GIT_BASE}/openstack/quantum.git}
-QUANTUM_BRANCH=${QUANTUM_BRANCH:-master}
-
-# quantum client
-QUANTUMCLIENT_REPO=${QUANTUMCLIENT_REPO:-${GIT_BASE}/openstack/python-quantumclient.git}
-QUANTUMCLIENT_BRANCH=${QUANTUMCLIENT_BRANCH:-master}
-
 # Tempest test suite
 TEMPEST_REPO=${TEMPEST_REPO:-${GIT_BASE}/openstack/tempest.git}
 TEMPEST_BRANCH=${TEMPEST_BRANCH:-master}
 
-# heat service
-HEAT_REPO=${HEAT_REPO:-${GIT_BASE}/openstack/heat.git}
-HEAT_BRANCH=${HEAT_BRANCH:-master}
-
-# python heat client library
-HEATCLIENT_REPO=${HEATCLIENT_REPO:-${GIT_BASE}/openstack/python-heatclient.git}
-HEATCLIENT_BRANCH=${HEATCLIENT_BRANCH:-master}
-
-# ryu service
-RYU_REPO=${RYU_REPO:-${GIT_BASE}/osrg/ryu.git}
-RYU_BRANCH=${RYU_BRANCH:-master}
 
 # diskimage-builder
 BM_IMAGE_BUILD_REPO=${BM_IMAGE_BUILD_REPO:-${GIT_BASE}/stackforge/diskimage-builder.git}
@@ -157,10 +150,18 @@
 BM_POSEUR_REPO=${BM_POSEUR_REPO:-${GIT_BASE}/tripleo/bm_poseur.git}
 BM_POSEUR_BRANCH=${BM_POSEUR_BRANCH:-master}
 
-# pbr
-# Used to drive the setuptools configs
-PBR_REPO=${PBR_REPO:-${GIT_BASE}/openstack-dev/pbr.git}
-PBR_BRANCH=${PBR_BRANCH:-master}
+# a websockets/html5 or flash powered VNC console for vm instances
+NOVNC_REPO=${NOVNC_REPO:-${GIT_BASE}/kanaka/noVNC.git}
+NOVNC_BRANCH=${NOVNC_BRANCH:-master}
+
+# ryu service
+RYU_REPO=${RYU_REPO:-${GIT_BASE}/osrg/ryu.git}
+RYU_BRANCH=${RYU_BRANCH:-master}
+
+# a websockets/html5 or flash powered SPICE console for vm instances
+SPICE_REPO=${SPICE_REPO:-http://anongit.freedesktop.org/git/spice/spice-html5.git}
+SPICE_BRANCH=${SPICE_BRANCH:-master}
+
 
 # Nova hypervisor configuration.  We default to libvirt with **kvm** but will
 # drop back to **qemu** if we are unable to load the kvm module.  ``stack.sh`` can
@@ -184,18 +185,22 @@
         ;;
 esac
 
-# Specify a comma-separated list of UEC images to download and install into glance.
-# supported urls here are:
+
+# Images
+# ------
+
+# Specify a comma-separated list of images to download and install into glance.
+# Supported urls here are:
 #  * "uec-style" images:
 #     If the file ends in .tar.gz, uncompress the tarball and and select the first
 #     .img file inside it as the image.  If present, use "*-vmlinuz*" as the kernel
 #     and "*-initrd*" as the ramdisk
-#     example: http://cloud-images.ubuntu.com/releases/oneiric/release/ubuntu-11.10-server-cloudimg-amd64.tar.gz
+#     example: http://cloud-images.ubuntu.com/releases/precise/release/ubuntu-12.04-server-cloudimg-amd64.tar.gz
 #  * disk image (*.img,*.img.gz)
 #    if file ends in .img, then it will be uploaded and registered as a to
 #    glance as a disk image.  If it ends in .gz, it is uncompressed first.
 #    example:
-#      http://cloud-images.ubuntu.com/releases/oneiric/release/ubuntu-11.10-server-cloudimg-armel-disk1.img
+#      http://cloud-images.ubuntu.com/releases/precise/release/ubuntu-12.04-server-cloudimg-armel-disk1.img
 #      http://download.cirros-cloud.net/0.3.1/cirros-0.3.1-x86_64-rootfs.img.gz
 #  * OpenVZ image:
 #    OpenVZ uses its own format of image, and does not support UEC style images
@@ -222,11 +227,12 @@
         ;;
     vsphere)
         IMAGE_URLS="";;
-    *) # otherwise, use the uec style image (with kernel, ramdisk, disk)
+    *) # Default to Cirros with kernel, ramdisk and disk image
         DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-0.3.1-x86_64-uec}
         IMAGE_URLS=${IMAGE_URLS:-"http://download.cirros-cloud.net/0.3.1/cirros-0.3.1-x86_64-uec.tar.gz"};;
 esac
 
+
 # 5Gb default volume backing file size
 VOLUME_BACKING_FILE_SIZE=${VOLUME_BACKING_FILE_SIZE:-5130M}