Merge "lib/swift: the s3_token middleware should be provided by keystonemiddleware"
diff --git a/README.md b/README.md
index 04f5fd9..455e1c6 100644
--- a/README.md
+++ b/README.md
@@ -149,6 +149,10 @@
 
     KEYSTONE_USE_MOD_WSGI="True"
 
+Example (Nova):
+
+    NOVA_USE_MOD_WSGI="True"
+
 Example (Swift):
 
     SWIFT_USE_MOD_WSGI="True"
@@ -328,7 +332,7 @@
 You likely want to change your `localrc` section to run a scheduler that
 will balance VMs across hosts:
 
-    SCHEDULER=nova.scheduler.simple.SimpleScheduler
+    SCHEDULER=nova.scheduler.filter_scheduler.FilterScheduler
 
 You can then run many compute nodes, each of which should have a `stackrc`
 which includes the following, with the IP address of the above controller node:
diff --git a/files/apache-nova-api.template b/files/apache-nova-api.template
new file mode 100644
index 0000000..70ccedd
--- /dev/null
+++ b/files/apache-nova-api.template
@@ -0,0 +1,16 @@
+Listen %PUBLICPORT%
+
+<VirtualHost *:%PUBLICPORT%>
+    WSGIDaemonProcess nova-api processes=5 threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
+    WSGIProcessGroup nova-api
+    WSGIScriptAlias / %PUBLICWSGI%
+    WSGIApplicationGroup %{GLOBAL}
+    WSGIPassAuthorization On
+    <IfVersion >= 2.4>
+      ErrorLogFormat "%{cu}t %M"
+    </IfVersion>
+    ErrorLog /var/log/%APACHE_NAME%/nova-api.log
+    %SSLENGINE%
+    %SSLCERTFILE%
+    %SSLKEYFILE%
+</VirtualHost>
\ No newline at end of file
diff --git a/files/apache-nova-ec2-api.template b/files/apache-nova-ec2-api.template
new file mode 100644
index 0000000..ae4cf94
--- /dev/null
+++ b/files/apache-nova-ec2-api.template
@@ -0,0 +1,16 @@
+Listen %PUBLICPORT%
+
+<VirtualHost *:%PUBLICPORT%>
+    WSGIDaemonProcess nova-ec2-api processes=5 threads=1 user=%USER% display-name=%{GROUP} %VIRTUALENV%
+    WSGIProcessGroup nova-ec2-api
+    WSGIScriptAlias / %PUBLICWSGI%
+    WSGIApplicationGroup %{GLOBAL}
+    WSGIPassAuthorization On
+    <IfVersion >= 2.4>
+      ErrorLogFormat "%{cu}t %M"
+    </IfVersion>
+    ErrorLog /var/log/%APACHE_NAME%/nova-ec2-api.log
+    %SSLENGINE%
+    %SSLCERTFILE%
+    %SSLKEYFILE%
+</VirtualHost>
\ No newline at end of file
diff --git a/files/debs/swift b/files/debs/swift
index 0089d27..726786e 100644
--- a/files/debs/swift
+++ b/files/debs/swift
@@ -1,8 +1,5 @@
 curl
 make
 memcached
-# NOTE python-nose only exists because of swift functional job, we should probably
-# figure out a more consistent way of installing this from test-requirements.txt instead
-python-nose
 sqlite3
 xfsprogs
diff --git a/files/rpms-suse/general b/files/rpms-suse/general
index 2219426..42756d8 100644
--- a/files/rpms-suse/general
+++ b/files/rpms-suse/general
@@ -15,7 +15,6 @@
 openssl
 psmisc
 python-cmd2 # dist:opensuse-12.3
-python-pylint
 screen
 tar
 tcpdump
diff --git a/files/rpms-suse/horizon b/files/rpms-suse/horizon
index d1f378a..c45eae6 100644
--- a/files/rpms-suse/horizon
+++ b/files/rpms-suse/horizon
@@ -12,7 +12,5 @@
 python-dateutil
 python-eventlet
 python-mox
-python-nose
-python-pylint
 python-sqlalchemy-migrate
 python-xattr
diff --git a/files/rpms-suse/swift b/files/rpms-suse/swift
index 4b14098..9c0d188 100644
--- a/files/rpms-suse/swift
+++ b/files/rpms-suse/swift
@@ -8,7 +8,6 @@
 python-eventlet
 python-greenlet
 python-netifaces
-python-nose
 python-simplejson
 python-xattr
 sqlite3
diff --git a/files/rpms/general b/files/rpms/general
index e17d6d6..7b2c00a 100644
--- a/files/rpms/general
+++ b/files/rpms/general
@@ -14,7 +14,6 @@
 libxslt-devel
 pkgconfig
 psmisc
-pylint
 python-devel
 screen
 tar
diff --git a/files/rpms/horizon b/files/rpms/horizon
index 8d7f037..b2cf0de 100644
--- a/files/rpms/horizon
+++ b/files/rpms/horizon
@@ -1,6 +1,5 @@
 Django
 httpd # NOPRIME
 mod_wsgi  # NOPRIME
-pylint
 pyxattr
 pcre-devel  # pyScss
diff --git a/functions-common b/functions-common
index f2e7076..4d07c03 100644
--- a/functions-common
+++ b/functions-common
@@ -1625,14 +1625,38 @@
 # Uses global ``ENABLED_SERVICES``
 # disable_negated_services
 function disable_negated_services {
-    local tmpsvcs="${ENABLED_SERVICES}"
+    local to_remove=""
+    local remaining=""
+    local enabled=""
     local service
-    for service in ${tmpsvcs//,/ }; do
+
+    # build up list of services that should be removed; i.e. they
+    # begin with "-"
+    for service in ${ENABLED_SERVICES//,/ }; do
         if [[ ${service} == -* ]]; then
-            tmpsvcs=$(echo ${tmpsvcs}|sed -r "s/(,)?(-)?${service#-}(,)?/,/g")
+            to_remove+=",${service#-}"
+        else
+            remaining+=",${service}"
         fi
     done
-    ENABLED_SERVICES=$(_cleanup_service_list "$tmpsvcs")
+
+    # go through the service list.  if this service appears in the "to
+    # be removed" list, drop it
+    for service in ${remaining//,/ }; do
+        local remove
+        local add=1
+        for remove in ${to_remove//,/ }; do
+            if [[ ${remove} == ${service} ]]; then
+                add=0
+                break
+            fi
+        done
+        if [[ $add == 1 ]]; then
+            enabled="${enabled},$service"
+        fi
+    done
+
+    ENABLED_SERVICES=$(_cleanup_service_list "$enabled")
 }
 
 # disable_service() removes the services passed as argument to the
diff --git a/lib/ceph b/lib/ceph
index 76747cc..4068e26 100644
--- a/lib/ceph
+++ b/lib/ceph
@@ -279,7 +279,7 @@
     # configure Nova service options, ceph pool, ceph user and ceph key
     sudo ceph -c ${CEPH_CONF_FILE} osd pool set ${NOVA_CEPH_POOL} size ${CEPH_REPLICAS}
     if [[ $CEPH_REPLICAS -ne 1 ]]; then
-        sudo -c ${CEPH_CONF_FILE} ceph osd pool set ${NOVA_CEPH_POOL} crush_ruleset ${RULE_ID}
+        sudo ceph -c ${CEPH_CONF_FILE} osd pool set ${NOVA_CEPH_POOL} crush_ruleset ${RULE_ID}
     fi
 }
 
diff --git a/lib/cinder b/lib/cinder
index 6439903..eb0e1d7 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -77,9 +77,20 @@
 
 
 # Should cinder perform secure deletion of volumes?
-# Defaults to true, can be set to False to avoid this bug when testing:
+# Defaults to zero. Can also be set to none or shred.
+# This was previously CINDER_SECURE_DELETE (True or False).
+# Equivalents using CINDER_VOLUME_CLEAR are zero and none, respectively.
+# Set to none to avoid this bug when testing:
 # https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1023755
-CINDER_SECURE_DELETE=$(trueorfalse True CINDER_SECURE_DELETE)
+if [[ -n $CINDER_SECURE_DELETE ]]; then
+    CINDER_SECURE_DELETE=$(trueorfalse True CINDER_SECURE_DELETE)
+    if [[ $CINDER_SECURE_DELETE == "False" ]]; then
+        CINDER_VOLUME_CLEAR_DEFAULT="none"
+    fi
+    DEPRECATED_TEXT="$DEPRECATED_TEXT\nConfigure secure Cinder volume deletion using CINDER_VOLUME_CLEAR instead of CINDER_SECURE_DELETE.\n"
+fi
+CINDER_VOLUME_CLEAR=${CINDER_VOLUME_CLEAR:-${CINDER_VOLUME_CLEAR_DEFAULT:-zero}}
+CINDER_VOLUME_CLEAR=$(echo ${CINDER_VOLUME_CLEAR} | tr '[:upper:]' '[:lower:]')
 
 # Cinder reports allocations back to the scheduler on periodic intervals
 # it turns out we can get an "out of space" issue when we run tests too
@@ -256,9 +267,8 @@
 
     iniset_rpc_backend cinder $CINDER_CONF
 
-    if [[ "$CINDER_SECURE_DELETE" == "False" ]]; then
-        iniset $CINDER_CONF DEFAULT secure_delete False
-        iniset $CINDER_CONF DEFAULT volume_clear none
+    if [[ "$CINDER_VOLUME_CLEAR" == "none" ]] || [[ "$CINDER_VOLUME_CLEAR" == "zero" ]] || [[ "$CINDER_VOLUME_CLEAR" == "shred" ]]; then
+        iniset $CINDER_CONF DEFAULT volume_clear $CINDER_VOLUME_CLEAR
     fi
 
     # Format logging
diff --git a/lib/neutron_plugins/ml2 b/lib/neutron_plugins/ml2
index abe6ea7..8853777 100644
--- a/lib/neutron_plugins/ml2
+++ b/lib/neutron_plugins/ml2
@@ -104,8 +104,10 @@
         iniset /$Q_PLUGIN_CONF_FILE securitygroup firewall_driver neutron.agent.firewall.NoopFirewallDriver
     fi
 
-    # Since we enable the tunnel TypeDrivers, also enable a local_ip
-    iniset /$Q_PLUGIN_CONF_FILE ovs local_ip $TUNNEL_ENDPOINT_IP
+    if [[ "$ENABLE_TENANT_TUNNELS" == "True" ]]; then
+        # Set local_ip if TENANT_TUNNELS are enabled.
+        iniset /$Q_PLUGIN_CONF_FILE ovs local_ip $TUNNEL_ENDPOINT_IP
+    fi
 
     populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2 mechanism_drivers=$Q_ML2_PLUGIN_MECHANISM_DRIVERS
 
diff --git a/lib/nova b/lib/nova
index 807dfce..6ac9da3 100644
--- a/lib/nova
+++ b/lib/nova
@@ -16,6 +16,7 @@
 #
 # - install_nova
 # - configure_nova
+# - _config_nova_apache_wsgi
 # - create_nova_conf
 # - init_nova
 # - start_nova
@@ -62,6 +63,15 @@
 # Expect to remove in L or M.
 NOVA_API_VERSION=${NOVA_API_VERSION-default}
 
+if is_suse; then
+    NOVA_WSGI_DIR=${NOVA_WSGI_DIR:-/srv/www/htdocs/nova}
+else
+    NOVA_WSGI_DIR=${NOVA_WSGI_DIR:-/var/www/nova}
+fi
+
+# Toggle for deploying Nova-API under HTTPD + mod_wsgi
+NOVA_USE_MOD_WSGI=${NOVA_USE_MOD_WSGI:-False}
+
 if is_ssl_enabled_service "nova" || is_service_enabled tls-proxy; then
     NOVA_SERVICE_PROTOCOL="https"
     EC2_SERVICE_PROTOCOL="https"
@@ -223,6 +233,64 @@
     #fi
 }
 
+# _cleanup_nova_apache_wsgi() - Remove wsgi files, disable and remove apache vhost file
+function _cleanup_nova_apache_wsgi {
+    sudo rm -f $NOVA_WSGI_DIR/*
+    sudo rm -f $(apache_site_config_for nova-api)
+    sudo rm -f $(apache_site_config_for nova-ec2-api)
+}
+
+# _config_nova_apache_wsgi() - Set WSGI config files of Keystone
+function _config_nova_apache_wsgi {
+    sudo mkdir -p $NOVA_WSGI_DIR
+
+    local nova_apache_conf=$(apache_site_config_for nova-api)
+    local nova_ec2_apache_conf=$(apache_site_config_for nova-ec2-api)
+    local nova_ssl=""
+    local nova_certfile=""
+    local nova_keyfile=""
+    local nova_api_port=$NOVA_SERVICE_PORT
+    local nova_ec2_api_port=$EC2_SERVICE_PORT
+    local venv_path=""
+
+    if is_ssl_enabled_service nova-api; then
+        nova_ssl="SSLEngine On"
+        nova_certfile="SSLCertificateFile $NOVA_SSL_CERT"
+        nova_keyfile="SSLCertificateKeyFile $NOVA_SSL_KEY"
+    fi
+    if [[ ${USE_VENV} = True ]]; then
+        venv_path="python-path=${PROJECT_VENV["nova"]}/lib/python2.7/site-packages"
+    fi
+
+    # copy proxy vhost and wsgi helper files
+    sudo cp $NOVA_DIR/nova/wsgi/nova-api.py $NOVA_WSGI_DIR/nova-api
+    sudo cp $NOVA_DIR/nova/wsgi/nova-ec2-api.py $NOVA_WSGI_DIR/nova-ec2-api
+
+    sudo cp $FILES/apache-nova-api.template $nova_apache_conf
+    sudo sed -e "
+        s|%PUBLICPORT%|$nova_api_port|g;
+        s|%APACHE_NAME%|$APACHE_NAME|g;
+        s|%PUBLICWSGI%|$NOVA_WSGI_DIR/nova-api|g;
+        s|%SSLENGINE%|$nova_ssl|g;
+        s|%SSLCERTFILE%|$nova_certfile|g;
+        s|%SSLKEYFILE%|$nova_keyfile|g;
+        s|%USER%|$STACK_USER|g;
+        s|%VIRTUALENV%|$venv_path|g
+    " -i $nova_apache_conf
+
+    sudo cp $FILES/apache-nova-ec2-api.template $nova_ec2_apache_conf
+    sudo sed -e "
+        s|%PUBLICPORT%|$nova_ec2_api_port|g;
+        s|%APACHE_NAME%|$APACHE_NAME|g;
+        s|%PUBLICWSGI%|$NOVA_WSGI_DIR/nova-ec2-api|g;
+        s|%SSLENGINE%|$nova_ssl|g;
+        s|%SSLCERTFILE%|$nova_certfile|g;
+        s|%SSLKEYFILE%|$nova_keyfile|g;
+        s|%USER%|$STACK_USER|g;
+        s|%VIRTUALENV%|$venv_path|g
+    " -i $nova_ec2_apache_conf
+}
+
 # configure_nova() - Set config files, create data dirs, etc
 function configure_nova {
     # Put config files in ``/etc/nova`` for everyone to find
@@ -392,7 +460,6 @@
     iniset $NOVA_CONF DEFAULT debug "$ENABLE_DEBUG_LOG_LEVEL"
     if [ "$NOVA_ALLOW_MOVE_TO_SAME_HOST" == "True" ]; then
         iniset $NOVA_CONF DEFAULT allow_resize_to_same_host "True"
-        iniset $NOVA_CONF DEFAULT allow_migrate_to_same_host "True"
     fi
     iniset $NOVA_CONF DEFAULT api_paste_config "$NOVA_API_PASTE_INI"
     iniset $NOVA_CONF DEFAULT rootwrap_config "$NOVA_CONF_DIR/rootwrap.conf"
@@ -453,12 +520,16 @@
         iniset $NOVA_CONF DEFAULT force_config_drive "$FORCE_CONFIG_DRIVE"
     fi
     # Format logging
-    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
+    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ] && [ "$NOVA_USE_MOD_WSGI" == "False" ]  ; then
         setup_colorized_logging $NOVA_CONF DEFAULT
     else
         # Show user_name and project_name instead of user_id and project_id
         iniset $NOVA_CONF DEFAULT logging_context_format_string "%(asctime)s.%(msecs)03d %(levelname)s %(name)s [%(request_id)s %(user_name)s %(project_name)s] %(instance)s%(message)s"
     fi
+    if [ "$NOVA_USE_MOD_WSGI" == "True" ]; then
+        _config_nova_apache_wsgi
+    fi
+
     if is_service_enabled ceilometer; then
         iniset $NOVA_CONF DEFAULT instance_usage_audit "True"
         iniset $NOVA_CONF DEFAULT instance_usage_audit_period "hour"
@@ -655,6 +726,13 @@
     git_clone $NOVA_REPO $NOVA_DIR $NOVA_BRANCH
     setup_develop $NOVA_DIR
     sudo install -D -m 0644 -o $STACK_USER {$NOVA_DIR/tools/,/etc/bash_completion.d/}nova-manage.bash_completion
+
+    if [ "$NOVA_USE_MOD_WSGI" == "True" ]; then
+        install_apache_wsgi
+        if is_ssl_enabled_service "nova-api"; then
+            enable_mod_ssl
+        fi
+    fi
 }
 
 # start_nova_api() - Start the API process ahead of other things
@@ -671,7 +749,18 @@
     local old_path=$PATH
     export PATH=$NOVA_BIN_DIR:$PATH
 
-    run_process n-api "$NOVA_BIN_DIR/nova-api"
+    # If the site is not enabled then we are in a grenade scenario
+    local enabled_site_file=$(apache_site_config_for nova-api)
+    if [ -f ${enabled_site_file} ] && [ "$NOVA_USE_MOD_WSGI" == "True" ]; then
+        enable_apache_site nova-api
+        enable_apache_site nova-ec2-api
+        restart_apache_server
+        tail_log nova /var/log/$APACHE_NAME/nova-api.log
+        tail_log nova /var/log/$APACHE_NAME/nova-ec2-api.log
+    else
+        run_process n-api "$NOVA_BIN_DIR/nova-api"
+    fi
+
     echo "Waiting for nova-api to start..."
     if ! wait_for_service $SERVICE_TIMEOUT $service_protocol://$SERVICE_HOST:$service_port; then
         die $LINENO "nova-api did not start"
@@ -780,6 +869,13 @@
 }
 
 function stop_nova_rest {
+    if [ "$NOVA_USE_MOD_WSGI" == "True" ]; then
+        disable_apache_site nova-api
+        disable_apache_site nova-ec2-api
+        restart_apache_server
+    else
+        stop_process n-api
+    fi
     # Kill the nova screen windows
     # Some services are listed here twice since more than one instance
     # of a service may be running in certain configs.
diff --git a/lib/tempest b/lib/tempest
index cd8fbd7..6ce245a 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -364,6 +364,8 @@
     iniset $TEMPEST_CONFIG compute-feature-enabled api_extensions $compute_api_extensions
     # TODO(mriedem): Remove the preserve_ports flag when Juno is end of life.
     iniset $TEMPEST_CONFIG compute-feature-enabled preserve_ports True
+    # TODO(gilliard): Remove the live_migrate_paused_instances flag when Juno is end of life.
+    iniset $TEMPEST_CONFIG compute-feature-enabled live_migrate_paused_instances True
 
     # Network
     iniset $TEMPEST_CONFIG network api_version 2.0
diff --git a/stack.sh b/stack.sh
index 3925bb0..f0aafaf 100755
--- a/stack.sh
+++ b/stack.sh
@@ -705,24 +705,17 @@
 # Virtual Environment
 # -------------------
 
+# Install required infra support libraries
+install_infra
+
 # Pre-build some problematic wheels
 if [[ -n ${WHEELHOUSE:-} && ! -d ${WHEELHOUSE:-} ]]; then
     source $TOP_DIR/tools/build_wheels.sh
-
-    # Due to https://bugs.launchpad.net/swift/+bug/1451992 we have to import
-    # this package with root once so the CFFI bindings can be built. We have
-    # to therefore install it so we can import it.
-    pip_install xattr
-    sudo python -c "import xattr"
 fi
 
 
 # Extras Pre-install
 # ------------------
-
-# Install required infra support libraries
-install_infra
-
 # Phase: pre-install
 run_phase stack pre-install
 
diff --git a/stackrc b/stackrc
index 2a49ea5..3c08b15 100644
--- a/stackrc
+++ b/stackrc
@@ -536,7 +536,7 @@
 #IMAGE_URLS="http://smoser.brickies.net/ubuntu/ttylinux-uec/ttylinux-uec-amd64-11.2_2.6.35-15_1.tar.gz" # old ttylinux-uec image
 #IMAGE_URLS="http://download.cirros-cloud.net/${CIRROS_VERSION}/cirros-${CIRROS_VERSION}-${CIRROS_ARCH}-disk.img" # cirros full disk image
 
-CIRROS_VERSION=${CIRROS_VERSION:-"0.3.2"}
+CIRROS_VERSION=${CIRROS_VERSION:-"0.3.4"}
 CIRROS_ARCH=${CIRROS_ARCH:-"x86_64"}
 
 # Set default image based on ``VIRT_DRIVER`` and ``LIBVIRT_TYPE``, either of
diff --git a/tests/test_functions.sh b/tests/test_functions.sh
index f8e2c9e..1d82792 100755
--- a/tests/test_functions.sh
+++ b/tests/test_functions.sh
@@ -127,7 +127,15 @@
 test_disable_negated_services 'b,a,-a' 'b'
 test_disable_negated_services 'a,b,-a' 'b'
 test_disable_negated_services 'a,-a,b' 'b'
-
+test_disable_negated_services 'a,aa,-a' 'aa'
+test_disable_negated_services 'aa,-a' 'aa'
+test_disable_negated_services 'a_a, -a_a' ''
+test_disable_negated_services 'a-b, -a-b' ''
+test_disable_negated_services 'a-b, b, -a-b' 'b'
+test_disable_negated_services 'a,-a,av2,b' 'av2,b'
+test_disable_negated_services 'a,aa,-a' 'aa'
+test_disable_negated_services 'a,av2,-a,a' 'av2'
+test_disable_negated_services 'a,-a,av2' 'av2'
 
 echo "Testing is_package_installed()"
 
diff --git a/tools/build_wheels.sh b/tools/build_wheels.sh
index c57568f..14c2999 100755
--- a/tools/build_wheels.sh
+++ b/tools/build_wheels.sh
@@ -60,6 +60,18 @@
 # Install modern pip and wheel
 PIP_VIRTUAL_ENV=$TMP_VENV_PATH pip_install -U pip wheel
 
+# BUG: cffi has a lot of issues. It has no stable ABI, if installed
+# code is built with a different ABI than the one that's detected at
+# load time, it tries to compile on the fly for the new ABI in the
+# install location (which will probably be /usr and not
+# writable). Also cffi is often included via setup_requires by
+# packages, which have different install rules (allowing betas) than
+# pip has.
+#
+# Because of this we must pip install cffi into the venv to build
+# wheels.
+PIP_VIRTUAL_ENV=$TMP_VENV_PATH pip_install_gr cffi
+
 # ``VENV_PACKAGES`` is a list of packages we want to pre-install
 VENV_PACKAGE_FILE=$FILES/venv-requirements.txt
 if [[ -r $VENV_PACKAGE_FILE ]]; then
diff --git a/tools/worlddump.py b/tools/worlddump.py
index 8dd455c..cb32510 100755
--- a/tools/worlddump.py
+++ b/tools/worlddump.py
@@ -61,6 +61,17 @@
     print dfraw
 
 
+def iptables_dump():
+    tables = ['filter', 'nat', 'mangle']
+    print """
+IP Tables Dump
+===============
+"""
+    for table in tables:
+        print os.popen("sudo iptables --line-numbers -L -nv -t %s"
+                       % table).read()
+
+
 def process_list():
     print """
 Process Listing
@@ -79,6 +90,7 @@
         os.dup2(f.fileno(), sys.stdout.fileno())
         disk_space()
         process_list()
+        iptables_dump()
 
 
 if __name__ == '__main__':
diff --git a/tools/xen/README.md b/tools/xen/README.md
index c8f47be..61694e9 100644
--- a/tools/xen/README.md
+++ b/tools/xen/README.md
@@ -97,7 +97,7 @@
     # 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.2/cirros-0.3.2-x86_64-uec.tar.gz"
+    http://download.cirros-cloud.net/0.3.4/cirros-0.3.4-x86_64-uec.tar.gz"
 
     # Explicitly set virt driver
     VIRT_DRIVER=xenserver