Merge "docs: add a blurb in the single-vm doc about cloud-init log output"
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
index fe23d6c..983f5c0 100644
--- a/doc/source/configuration.rst
+++ b/doc/source/configuration.rst
@@ -383,6 +383,24 @@
 ``files/keystone_data.sh``
 
 
+Guest Images
+------------
+
+Images provided in URLS via the comma-separated ``IMAGE_URLS``
+variable will be downloaded and uploaded to glance by DevStack.
+
+Default guest-images are predefined for each type of hypervisor and
+their testing-requirements in ``stack.sh``.  Setting
+``DOWNLOAD_DEFAULT_IMAGES=False`` will prevent DevStack downloading
+these default images; in that case, you will want to populate
+``IMAGE_URLS`` with sufficient images to satisfy testing-requirements.
+
+    ::
+
+        DOWNLOAD_DEFAULT_IMAGES=False
+        IMAGE_URLS="http://foo.bar.com/image.qcow,"
+        IMAGE_URLS+="http://foo.bar.com/image2.qcow"
+
 IP Version
 ----------
 
diff --git a/lib/ceilometer b/lib/ceilometer
index 3df75b7..d1cc862 100644
--- a/lib/ceilometer
+++ b/lib/ceilometer
@@ -102,9 +102,6 @@
 CEILOMETER_COORDINATION_URL=${CEILOMETER_COORDINATION_URL:-}
 CEILOMETER_PIPELINE_INTERVAL=${CEILOMETER_PIPELINE_INTERVAL:-}
 
-# Tell Tempest this project is present
-TEMPEST_SERVICES+=,ceilometer
-
 
 # Functions
 # ---------
diff --git a/lib/cinder b/lib/cinder
index e5ed2db..26277cc 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -108,9 +108,6 @@
 
 CINDER_ISCSI_HELPER=${CINDER_ISCSI_HELPER:-tgtadm}
 
-# Tell Tempest this project is present
-TEMPEST_SERVICES+=,cinder
-
 
 # Source the enabled backends
 if is_service_enabled c-vol && [[ -n "$CINDER_ENABLED_BACKENDS" ]]; then
diff --git a/lib/databases/mysql b/lib/databases/mysql
index 7ae9a93..ada56a7 100644
--- a/lib/databases/mysql
+++ b/lib/databases/mysql
@@ -92,14 +92,12 @@
 
     # Change bind-address from localhost (127.0.0.1) to any (::) and
     # set default db type to InnoDB
-    sudo bash -c "source $TOP_DIR/functions && \
-        iniset $my_conf mysqld bind-address "$SERVICE_LISTEN_ADDRESS" && \
-        iniset $my_conf mysqld sql_mode STRICT_ALL_TABLES && \
-        iniset $my_conf mysqld default-storage-engine InnoDB && \
-        iniset $my_conf mysqld max_connections 1024 && \
-        iniset $my_conf mysqld query_cache_type OFF && \
-        iniset $my_conf mysqld query_cache_size 0"
-
+    iniset -sudo $my_conf mysqld bind-address "$SERVICE_LISTEN_ADDRESS"
+    iniset -sudo $my_conf mysqld sql_mode STRICT_ALL_TABLES
+    iniset -sudo $my_conf mysqld default-storage-engine InnoDB
+    iniset -sudo $my_conf mysqld max_connections 1024
+    iniset -sudo $my_conf mysqld query_cache_type OFF
+    iniset -sudo $my_conf mysqld query_cache_size 0
 
     if [[ "$DATABASE_QUERY_LOGGING" == "True" ]]; then
         echo_summary "Enabling MySQL query logging"
@@ -115,12 +113,10 @@
 
         # Turn on slow query log, log all queries (any query taking longer than
         # 0 seconds) and log all non-indexed queries
-        sudo bash -c "source $TOP_DIR/functions && \
-            iniset $my_conf mysqld slow-query-log 1 && \
-            iniset $my_conf mysqld slow-query-log-file $slow_log && \
-            iniset $my_conf mysqld long-query-time 0 && \
-            iniset $my_conf mysqld log-queries-not-using-indexes 1"
-
+        iniset -sudo $my_conf mysqld slow-query-log 1
+        iniset -sudo $my_conf mysqld slow-query-log-file $slow_log
+        iniset -sudo $my_conf mysqld long-query-time 0
+        iniset -sudo $my_conf mysqld log-queries-not-using-indexes 1
     fi
 
     restart_service $mysql
diff --git a/lib/glance b/lib/glance
index b1b0f32..7be3a84 100644
--- a/lib/glance
+++ b/lib/glance
@@ -75,9 +75,6 @@
 GLANCE_SEARCH_PORT_INT=${GLANCE_SEARCH_PORT_INT:-19393}
 GLANCE_SEARCH_HOSTPORT=${GLANCE_SEARCH_HOSTPORT:-$GLANCE_SERVICE_HOST:$GLANCE_SEARCH_PORT}
 
-# Tell Tempest this project is present
-TEMPEST_SERVICES+=,glance
-
 # Functions
 # ---------
 
diff --git a/lib/heat b/lib/heat
index cedddd2..3e6975a 100644
--- a/lib/heat
+++ b/lib/heat
@@ -53,6 +53,8 @@
 HEAT_API_HOST=${HEAT_API_HOST:-$HOST_IP}
 HEAT_API_PORT=${HEAT_API_PORT:-8004}
 
+# Support entry points installation of console scripts
+HEAT_BIN_DIR=$(get_python_exec_prefix)
 
 # other default options
 if [[ "$HEAT_STANDALONE" = "True" ]]; then
@@ -64,10 +66,6 @@
     HEAT_DEFERRED_AUTH=${HEAT_DEFERRED_AUTH:-trusts}
 fi
 
-# Tell Tempest this project is present
-TEMPEST_SERVICES+=,heat
-
-
 # Functions
 # ---------
 
@@ -190,7 +188,7 @@
     # (re)create heat database
     recreate_database heat
 
-    $HEAT_DIR/bin/heat-manage db_sync
+    $HEAT_BIN_DIR/heat-manage db_sync
     create_heat_cache_dir
 }
 
@@ -227,10 +225,10 @@
 
 # start_heat() - Start running processes, including screen
 function start_heat {
-    run_process h-eng "$HEAT_DIR/bin/heat-engine --config-file=$HEAT_CONF"
-    run_process h-api "$HEAT_DIR/bin/heat-api --config-file=$HEAT_CONF"
-    run_process h-api-cfn "$HEAT_DIR/bin/heat-api-cfn --config-file=$HEAT_CONF"
-    run_process h-api-cw "$HEAT_DIR/bin/heat-api-cloudwatch --config-file=$HEAT_CONF"
+    run_process h-eng "$HEAT_BIN_DIR/heat-engine --config-file=$HEAT_CONF"
+    run_process h-api "$HEAT_BIN_DIR/heat-api --config-file=$HEAT_CONF"
+    run_process h-api-cfn "$HEAT_BIN_DIR/heat-api-cfn --config-file=$HEAT_CONF"
+    run_process h-api-cw "$HEAT_BIN_DIR/heat-api-cloudwatch --config-file=$HEAT_CONF"
 }
 
 # stop_heat() - Stop running processes
diff --git a/lib/horizon b/lib/horizon
index 9fe0aa8..b2539d1 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -35,10 +35,6 @@
 # The example file in Horizon repo is used by default.
 HORIZON_SETTINGS=${HORIZON_SETTINGS:-$HORIZON_DIR/openstack_dashboard/local/local_settings.py.example}
 
-# Tell Tempest this project is present
-TEMPEST_SERVICES+=,horizon
-
-
 # Functions
 # ---------
 
diff --git a/lib/ironic b/lib/ironic
index 6fb5184..9069d79 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -115,9 +115,6 @@
 IRONIC_SERVICE_PORT=${IRONIC_SERVICE_PORT:-6385}
 IRONIC_HOSTPORT=${IRONIC_HOSTPORT:-$SERVICE_HOST:$IRONIC_SERVICE_PORT}
 
-# Tell Tempest this project is present
-TEMPEST_SERVICES+=,ironic
-
 # Enable iPXE
 IRONIC_IPXE_ENABLED=$(trueorfalse False IRONIC_IPXE_ENABLED)
 IRONIC_HTTP_DIR=${IRONIC_HTTP_DIR:-$IRONIC_DATA_DIR/httpboot}
diff --git a/lib/neutron-legacy b/lib/neutron-legacy
old mode 100644
new mode 100755
index dab0481..d1865d8
--- a/lib/neutron-legacy
+++ b/lib/neutron-legacy
@@ -326,7 +326,9 @@
 # ---------------------------------
 
 # Please refer to ``lib/neutron_plugins/README.md`` for details.
-source $TOP_DIR/lib/neutron_plugins/$Q_PLUGIN
+if [ -f $TOP_DIR/lib/neutron_plugins/$Q_PLUGIN ]; then
+    source $TOP_DIR/lib/neutron_plugins/$Q_PLUGIN
+fi
 
 # Agent loadbalancer service plugin functions
 # -------------------------------------------
@@ -356,10 +358,6 @@
     Q_USE_SECGROUP=False
 fi
 
-# Tell Tempest this project is present
-TEMPEST_SERVICES+=,neutron
-
-
 # Save trace setting
 XTRACE=$(set +o | grep xtrace)
 set +o xtrace
@@ -828,11 +826,11 @@
         fi
 
         if [[ "$IP_BRD" != "" ]]; then
-            IP_ADD="sudo ip addr del $IP_BRD dev $from_intf"
-            IP_DEL="sudo ip addr add $IP_BRD dev $to_intf"
+            IP_DEL="sudo ip addr del $IP_BRD dev $from_intf"
+            IP_ADD="sudo ip addr add $IP_BRD dev $to_intf"
         fi
 
-        $IP_ADD; $IP_DEL; $ADD_OVS_PORT; $ADD_DEFAULT_ROUTE
+        $IP_DEL; $IP_ADD; $ADD_OVS_PORT; $ADD_DEFAULT_ROUTE
     fi
 }
 
diff --git a/lib/nova b/lib/nova
index 087cac6..2afaa81 100644
--- a/lib/nova
+++ b/lib/nova
@@ -64,6 +64,11 @@
 # Expect to remove in L or M.
 NOVA_API_VERSION=${NOVA_API_VERSION-default}
 
+# NOVA_V2_LEGACY defines whether we force the Nova v2.0 enpoint onto
+# the Nova v2.0 legacy code base. Remove this option once the Nova
+# v2.0 legacy codebase is removed.
+NOVA_V2_LEGACY=$(trueorfalse False NOVA_V2_LEGACY)
+
 if is_suse; then
     NOVA_WSGI_DIR=${NOVA_WSGI_DIR:-/srv/www/htdocs/nova}
 else
@@ -167,10 +172,6 @@
 TEST_FLOATING_POOL=${TEST_FLOATING_POOL:-test}
 TEST_FLOATING_RANGE=${TEST_FLOATING_RANGE:-192.168.253.0/29}
 
-# Tell Tempest this project is present
-TEMPEST_SERVICES+=,nova
-
-
 # Functions
 # ---------
 
@@ -317,6 +318,13 @@
         if [[ "$NOVA_API_VERSION" == "v21default" ]]; then
             sed -i s/": openstack_compute_api_v2$"/": openstack_compute_api_v21"/ "$NOVA_API_PASTE_INI"
         fi
+
+        # For setting up an environment where v2.0 is running on the
+        # v2.0 legacy code base.
+        if [[ "$NOVA_V2_LEGACY" == "True" ]]; then
+            sed -i s@"^/v2: openstack_compute_api_v21_legacy_v2_compatible$"@"/v2: openstack_compute_api_legacy_v2"@ \
+                "$NOVA_API_PASTE_INI"
+        fi
     fi
 
     if is_service_enabled n-cpu; then
@@ -417,15 +425,16 @@
                 nova_api_url="$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST/compute"
             fi
 
-            get_or_create_service "nova" "compute" "Nova Compute Service"
-            get_or_create_endpoint "compute" \
+            get_or_create_service "nova_legacy" "compute_legacy" \
+                "Nova Compute Service (Legacy 2.0)"
+            get_or_create_endpoint "compute_legacy" \
                 "$REGION_NAME" \
                 "$nova_api_url/v2/\$(tenant_id)s" \
                 "$nova_api_url/v2/\$(tenant_id)s" \
                 "$nova_api_url/v2/\$(tenant_id)s"
 
-            get_or_create_service "novav21" "computev21" "Nova Compute Service V2.1"
-            get_or_create_endpoint "computev21" \
+            get_or_create_service "nova" "compute" "Nova Compute Service"
+            get_or_create_endpoint "compute" \
                 "$REGION_NAME" \
                 "$nova_api_url/v2.1/\$(tenant_id)s" \
                 "$nova_api_url/v2.1/\$(tenant_id)s" \
diff --git a/lib/swift b/lib/swift
index fdeae9b..6b61274 100644
--- a/lib/swift
+++ b/lib/swift
@@ -141,10 +141,6 @@
 # Toggle for deploying Swift under HTTPD + mod_wsgi
 SWIFT_USE_MOD_WSGI=${SWIFT_USE_MOD_WSGI:-False}
 
-# Tell Tempest this project is present
-TEMPEST_SERVICES+=,swift
-
-
 # Functions
 # ---------
 
diff --git a/lib/tempest b/lib/tempest
index be24da6..d372e0f 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -361,6 +361,14 @@
         iniset $TEMPEST_CONFIG compute fixed_network_name $PRIVATE_NETWORK_NAME
     fi
 
+    # Set the service catalog entry for Tempest to run on. Typically
+    # used to try different compute API version targets. The tempest
+    # default if 'compute', which is typically valid, so only set this
+    # if you want to change it.
+    if [[ -n "$TEMPEST_COMPUTE_TYPE" ]]; then
+        iniset $TEMPEST_CONFIG compute catalog_type $TEMPEST_COMPUTE_TYPE
+    fi
+
     # Compute Features
     # Run ``verify_tempest_config -ur`` to retrieve enabled extensions on API endpoints
     # NOTE(mtreinish): This must be done after auth settings are added to the tempest config
@@ -390,6 +398,10 @@
     # neutron.allow_duplicate_networks option was removed from nova in Liberty
     # and is now the default behavior.
     iniset $TEMPEST_CONFIG compute-feature-enabled allow_duplicate_networks ${NOVA_ALLOW_DUPLICATE_NETWORKS:-True}
+    if is_service_enabled n-cell; then
+        # Cells doesn't support shelving/unshelving
+        iniset $TEMPEST_CONFIG compute-feature-enabled shelve False
+    fi
 
     # Network
     iniset $TEMPEST_CONFIG network api_version 2.0
@@ -536,6 +548,11 @@
     fi
 
     # ``service_available``
+    #
+    # this tempest service list needs to be all the services that
+    # tempest supports, otherwise we can have an erroneous set of
+    # defaults (something defaulting true in Tempest, but not listed here).
+    TEMPEST_SERVICES="key,glance,nova,neutron,cinder,swift,heat,ceilometer,horizon,sahara,ironic,trove,zaqar"
     for service in ${TEMPEST_SERVICES//,/ }; do
         if is_service_enabled $service ; then
             iniset $TEMPEST_CONFIG service_available $service "True"
@@ -546,7 +563,7 @@
 
     if is_ssl_enabled_service "key" || is_service_enabled tls-proxy; then
         # Use the ``BOTO_CONFIG`` environment variable to point to this file
-        iniset $BOTO_CONF Boto ca_certificates_file $SSL_BUNDLE_FILE
+        iniset -sudo $BOTO_CONF Boto ca_certificates_file $SSL_BUNDLE_FILE
         sudo chown $STACK_USER $BOTO_CONF
     fi
 
diff --git a/lib/zaqar b/lib/zaqar
index fdab3a2..aa21aac 100644
--- a/lib/zaqar
+++ b/lib/zaqar
@@ -59,10 +59,6 @@
 ZAQAR_SERVICE_PORT=${ZAQAR_SERVICE_PORT:-8888}
 ZAQAR_SERVICE_PROTOCOL=${ZAQAR_SERVICE_PROTOCOL:-$SERVICE_PROTOCOL}
 
-# Tell Tempest this project is present
-TEMPEST_SERVICES+=,zaqar
-
-
 # Functions
 # ---------
 
diff --git a/stackrc b/stackrc
index 760e2fc..ca897a1 100644
--- a/stackrc
+++ b/stackrc
@@ -2,6 +2,11 @@
 #
 # stackrc
 #
+
+# ensure we don't re-source this in the same environment
+[[ -z "$_DEVSTACK_STACKRC" ]] || return 0
+declare -r _DEVSTACK_STACKRC=1
+
 # Find the other rc files
 RC_DIR=$(cd $(dirname "${BASH_SOURCE:-$0}") && pwd)
 
@@ -78,12 +83,6 @@
 # services will rely on the local toggle variable (e.g. ``KEYSTONE_USE_MOD_WSGI``)
 ENABLE_HTTPD_MOD_WSGI_SERVICES=True
 
-# Tell Tempest which services are available.  The default is set here as
-# Tempest falls late in the configuration sequence.  This differs from
-# ``ENABLED_SERVICES`` in that the project names are used here rather than
-# the service names, i.e.: ``TEMPEST_SERVICES="key,glance,nova"``
-TEMPEST_SERVICES=""
-
 # Set the default Nova APIs to enable
 NOVA_ENABLED_APIS=ec2,osapi_compute,metadata
 
@@ -564,40 +563,47 @@
 # Set default image based on ``VIRT_DRIVER`` and ``LIBVIRT_TYPE``, either of
 # which may be set in ``local.conf``.  Also allow ``DEFAULT_IMAGE_NAME`` and
 # ``IMAGE_URLS`` to be set in the `localrc` section of ``local.conf``.
-case "$VIRT_DRIVER" in
-    openvz)
-        DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-ubuntu-12.04-x86_64}
-        IMAGE_URLS=${IMAGE_URLS:-"http://download.openvz.org/template/precreated/ubuntu-12.04-x86_64.tar.gz"};;
-    libvirt)
-        case "$LIBVIRT_TYPE" in
-            lxc) # the cirros root disk in the uec tarball is empty, so it will not work for lxc
-                DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-rootfs}
-                IMAGE_URLS=${IMAGE_URLS:-"http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-rootfs.img.gz"};;
-            *) # otherwise, use the uec style image (with kernel, ramdisk, disk)
-                DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-uec}
-                IMAGE_URLS=${IMAGE_URLS:-"http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-uec.tar.gz"};;
-        esac
-        ;;
-    vsphere)
-        DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-0.3.2-i386-disk.vmdk}
-        IMAGE_URLS=${IMAGE_URLS:-"http://partnerweb.vmware.com/programs/vmdkimage/cirros-0.3.2-i386-disk.vmdk"};;
-    xenserver)
-        DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-0.3.4-x86_64-disk}
-        IMAGE_URLS=${IMAGE_URLS:-"http://ca.downloads.xensource.com/OpenStack/cirros-0.3.4-x86_64-disk.vhd.tgz"}
-        IMAGE_URLS+=",http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-uec.tar.gz";;
-    ironic)
-        # Ironic can do both partition and full disk images, depending on the driver
-        if [[ "$IRONIC_DEPLOY_DRIVER" == "agent_ssh" ]]; then
-            DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-x86_64-disk}
-        else
-            DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-x86_64-uec}
-        fi
-        IMAGE_URLS=${IMAGE_URLS:-"http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-uec.tar.gz"}
-        IMAGE_URLS+=",http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-disk.img";;
-    *) # Default to Cirros with kernel, ramdisk and disk image
-        DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-uec}
-        IMAGE_URLS=${IMAGE_URLS:-"http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-uec.tar.gz"};;
-esac
+DOWNLOAD_DEFAULT_IMAGES=$(trueorfalse True DOWNLOAD_DEFAULT_IMAGES)
+if [[ "$DOWNLOAD_DEFAULT_IMAGES" == "True" ]]; then
+    if [[ -n "$IMAGE_URLS" ]]; then
+        IMAGE_URLS+=","
+    fi
+    case "$VIRT_DRIVER" in
+        openvz)
+            DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-ubuntu-12.04-x86_64}
+            IMAGE_URLS+="http://download.openvz.org/template/precreated/ubuntu-12.04-x86_64.tar.gz";;
+        libvirt)
+            case "$LIBVIRT_TYPE" in
+                lxc) # the cirros root disk in the uec tarball is empty, so it will not work for lxc
+                    DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-rootfs}
+                    IMAGE_URLS+="http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-rootfs.img.gz";;
+                *) # otherwise, use the uec style image (with kernel, ramdisk, disk)
+                    DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-uec}
+                    IMAGE_URLS+="http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-uec.tar.gz";;
+                esac
+            ;;
+        vsphere)
+            DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-0.3.2-i386-disk.vmdk}
+            IMAGE_URLS+="http://partnerweb.vmware.com/programs/vmdkimage/cirros-0.3.2-i386-disk.vmdk";;
+        xenserver)
+            DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-0.3.4-x86_64-disk}
+            IMAGE_URLS+="http://ca.downloads.xensource.com/OpenStack/cirros-0.3.4-x86_64-disk.vhd.tgz"
+            IMAGE_URLS+=",http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-uec.tar.gz";;
+        ironic)
+            # Ironic can do both partition and full disk images, depending on the driver
+            if [[ "$IRONIC_DEPLOY_DRIVER" == "agent_ssh" ]]; then
+                DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-x86_64-disk}
+            else
+                DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-x86_64-uec}
+            fi
+            IMAGE_URLS+="http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-uec.tar.gz"
+            IMAGE_URLS+=",http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-x86_64-disk.img";;
+        *) # Default to Cirros with kernel, ramdisk and disk image
+            DEFAULT_IMAGE_NAME=${DEFAULT_IMAGE_NAME:-cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-uec}
+            IMAGE_URLS+="http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-uec.tar.gz";;
+    esac
+    DOWNLOAD_DEFAULT_IMAGES=False
+fi
 
 # Staging Area for New Images, have them here for at least 24hrs for nodepool
 # to cache them otherwise the failure rates in the gate are too high
@@ -610,6 +616,13 @@
     fi
 fi
 
+# Detect duplicate values in IMAGE_URLS
+for image_url in ${IMAGE_URLS//,/ }; do
+    if [ $(echo "$IMAGE_URLS" | grep -o -F "$image_url" | wc -l) -gt 1 ]; then
+        die $LINENO "$image_url is duplicate, please remove it from IMAGE_URLS."
+    fi
+done
+
 # 10Gb default volume backing file size
 VOLUME_BACKING_FILE_SIZE=${VOLUME_BACKING_FILE_SIZE:-10250M}
 
diff --git a/tools/fixup_stuff.sh b/tools/fixup_stuff.sh
index 4fff57f..a601cf2 100755
--- a/tools/fixup_stuff.sh
+++ b/tools/fixup_stuff.sh
@@ -134,6 +134,31 @@
             sudo systemctl start iptables
         fi
     fi
+
+    if  [[ "$os_RELEASE" -ge "21" ]]; then
+        # requests ships vendored version of chardet/urllib3, but on
+        # fedora these are symlinked back to the primary versions to
+        # avoid duplication of code on disk.  This is fine when
+        # maintainers keep things in sync, but since devstack takes
+        # over and installs later versions via pip we can end up with
+        # incompatible versions.
+        #
+        # The rpm package is not removed to preserve the dependent
+        # packages like cloud-init; rather we remove the symlinks and
+        # force a re-install of requests so the vendored versions it
+        # wants are present.
+        #
+        # Realted issues:
+        # https://bugs.launchpad.net/glance/+bug/1476770
+        # https://bugzilla.redhat.com/show_bug.cgi?id=1253823
+
+        base_path=/usr/lib/python2.7/site-packages/requests/packages
+        if [ -L $base_path/chardet -o -L $base_path/urllib3 ]; then
+            sudo rm -f /usr/lib/python2.7/site-packages/requests/packages/{chardet,urllib3}
+            # install requests with the bundled urllib3 to avoid conflicts
+            pip_install --upgrade --force-reinstall requests
+        fi
+    fi
 fi
 
 # The version of pip(1.5.4) supported by python-virtualenv(1.11.4) has
diff --git a/tools/make_cert.sh b/tools/make_cert.sh
index cb93e57..2628b40 100755
--- a/tools/make_cert.sh
+++ b/tools/make_cert.sh
@@ -5,7 +5,7 @@
 # Create a CA hierarchy (if necessary) and server certificate
 #
 # This mimics the CA structure that DevStack sets up when ``tls_proxy`` is enabled
-# but in the curent directory unless ``DATA_DIR`` is set
+# but in the current directory unless ``DATA_DIR`` is set
 
 ENABLE_TLS=True
 DATA_DIR=${DATA_DIR:-`pwd`/ca-data}
diff --git a/tools/xen/README.md b/tools/xen/README.md
index 61694e9..6212cc5 100644
--- a/tools/xen/README.md
+++ b/tools/xen/README.md
@@ -94,11 +94,6 @@
     XENAPI_CONNECTION_URL="http://address_of_your_xenserver"
     VNCSERVER_PROXYCLIENT_ADDRESS=address_of_your_xenserver
 
-    # Download a vhd and a uec image
-    IMAGE_URLS="\
-    https://github.com/downloads/citrix-openstack/warehouse/cirros-0.3.0-x86_64-disk.vhd.tgz,\
-    http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-uec.tar.gz"
-
     # Explicitly set virt driver
     VIRT_DRIVER=xenserver