Merge "increase heat guests"
diff --git a/HACKING.rst b/HACKING.rst
index 5c15537..83455e3 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -20,7 +20,7 @@
 contains the usual links for blueprints, bugs, tec.
 
 __ contribute_
-.. _contribute: http://wiki.openstack.org/HowToContribute.
+.. _contribute: http://wiki.openstack.org/HowToContribute
 
 __ lp_
 .. _lp: https://launchpad.net/~devstack
@@ -231,7 +231,7 @@
 
 Bash Style Guidelines
 ~~~~~~~~~~~~~~~~~~~~~
-Devstack defines a bash set of best practices for maintaining large
+DevStack defines a bash set of best practices for maintaining large
 collections of bash scripts. These should be considered as part of the
 review process.
 
diff --git a/exercises/client-env.sh b/exercises/client-env.sh
index d955e4d..4e8259c 100755
--- a/exercises/client-env.sh
+++ b/exercises/client-env.sh
@@ -64,7 +64,7 @@
         STATUS_KEYSTONE="Skipped"
     else
         echo -e "\nTest Keystone"
-        if keystone catalog --service identity; then
+        if openstack endpoint show identity; then
             STATUS_KEYSTONE="Succeeded"
         else
             STATUS_KEYSTONE="Failed"
diff --git a/exercises/neutron-adv-test.sh b/exercises/neutron-adv-test.sh
index 0a24fe9..6679670 100755
--- a/exercises/neutron-adv-test.sh
+++ b/exercises/neutron-adv-test.sh
@@ -100,15 +100,6 @@
 DEMO1_ROUTER1_NET="demo1-net1"
 DEMO2_ROUTER1_NET="demo2-net1"
 
-KEYSTONE="keystone"
-
-# Manually create a token by querying keystone (sending JSON data).  Keystone
-# returns a token and catalog of endpoints.  We use python to parse the token
-# and save it.
-
-TOKEN=`keystone token-get | grep ' id ' | awk '{print $4}'`
-die_if_not_set $LINENO TOKEN "Keystone fail to get token"
-
 # Various functions
 # -----------------
 
@@ -150,21 +141,21 @@
 
 function get_tenant_id {
     local TENANT_NAME=$1
-    local TENANT_ID=`keystone tenant-list | grep " $TENANT_NAME " | head -n 1 | get_field 1`
+    local TENANT_ID=`openstack project list | grep " $TENANT_NAME " | head -n 1 | get_field 1`
     die_if_not_set $LINENO TENANT_ID "Failure retrieving TENANT_ID for $TENANT_NAME"
     echo "$TENANT_ID"
 }
 
 function get_user_id {
     local USER_NAME=$1
-    local USER_ID=`keystone user-list | grep $USER_NAME | awk '{print $2}'`
+    local USER_ID=`openstack user list | grep $USER_NAME | awk '{print $2}'`
     die_if_not_set $LINENO USER_ID "Failure retrieving USER_ID for $USER_NAME"
     echo "$USER_ID"
 }
 
 function get_role_id {
     local ROLE_NAME=$1
-    local ROLE_ID=`keystone role-list | grep $ROLE_NAME | awk '{print $2}'`
+    local ROLE_ID=`openstack role list | grep $ROLE_NAME | awk '{print $2}'`
     die_if_not_set $LINENO ROLE_ID "Failure retrieving ROLE_ID for $ROLE_NAME"
     echo "$ROLE_ID"
 }
@@ -199,28 +190,21 @@
 }
 
 function add_tenant {
-    local TENANT=$1
-    local USER=$2
-
-    $KEYSTONE tenant-create --name=$TENANT
-    $KEYSTONE user-create --name=$USER --pass=${ADMIN_PASSWORD}
-
-    local USER_ID=$(get_user_id $USER)
-    local TENANT_ID=$(get_tenant_id $TENANT)
-
-    $KEYSTONE user-role-add --user-id $USER_ID --role-id $(get_role_id Member) --tenant-id $TENANT_ID
+    openstack project create $1
+    openstack user create $2 --password ${ADMIN_PASSWORD} --project $1
+    openstack role add Member --project $1 --user $2
 }
 
 function remove_tenant {
     local TENANT=$1
     local TENANT_ID=$(get_tenant_id $TENANT)
-    $KEYSTONE tenant-delete $TENANT_ID
+    openstack project delete $TENANT_ID
 }
 
 function remove_user {
     local USER=$1
     local USER_ID=$(get_user_id $USER)
-    $KEYSTONE user-delete $USER_ID
+    openstack user delete $USER_ID
 }
 
 function create_tenants {
diff --git a/extras.d/80-opendaylight.sh b/extras.d/80-opendaylight.sh
index 57b4328..c3c85fc 100644
--- a/extras.d/80-opendaylight.sh
+++ b/extras.d/80-opendaylight.sh
@@ -14,6 +14,7 @@
         configure_opendaylight
         init_opendaylight
     elif [[ "$1" == "stack" && "$2" == "post-config" ]]; then
+        configure_ml2_odl
         # This has to start before Neutron
         start_opendaylight
     elif [[ "$1" == "stack" && "$2" == "post-extra" ]]; then
diff --git a/files/apts/n-api b/files/apts/n-api
index e0e5e7f..b4372d9 100644
--- a/files/apts/n-api
+++ b/files/apts/n-api
@@ -1,2 +1,3 @@
 python-dateutil
 msgpack-python
+fping
diff --git a/files/apts/nova b/files/apts/nova
index 69d0a35..38c99c7 100644
--- a/files/apts/nova
+++ b/files/apts/nova
@@ -15,6 +15,7 @@
 qemu-kvm # NOPRIME
 qemu # dist:wheezy,jessie NOPRIME
 libvirt-bin # NOPRIME
+pm-utils
 libjs-jquery-tablesorter # Needed for coverage html reports
 vlan
 curl
diff --git a/files/rpms-suse/n-api b/files/rpms-suse/n-api
index 0f08daa..6f59e60 100644
--- a/files/rpms-suse/n-api
+++ b/files/rpms-suse/n-api
@@ -1 +1,2 @@
 python-dateutil
+fping
diff --git a/files/rpms-suse/opendaylight b/files/rpms-suse/opendaylight
index d6c7146..f7fafff 100644
--- a/files/rpms-suse/opendaylight
+++ b/files/rpms-suse/opendaylight
@@ -1,4 +1,3 @@
 openvswitch # NOPRIME
-openvswitch-controller # NOPRIME
 openvswitch-switch # NOPRIME
 
diff --git a/files/rpms/horizon b/files/rpms/horizon
index 2dd24e0..38d349d 100644
--- a/files/rpms/horizon
+++ b/files/rpms/horizon
@@ -1,5 +1,4 @@
 Django
-django-registration
 gcc
 httpd # NOPRIME
 mod_wsgi  # NOPRIME
diff --git a/files/rpms/n-api b/files/rpms/n-api
index 0f08daa..6f59e60 100644
--- a/files/rpms/n-api
+++ b/files/rpms/n-api
@@ -1 +1,2 @@
 python-dateutil
+fping
diff --git a/lib/cinder b/lib/cinder
index dd2956a..dadbe40 100644
--- a/lib/cinder
+++ b/lib/cinder
@@ -274,6 +274,10 @@
     iniset $CINDER_CONF DEFAULT lock_path $CINDER_STATE_PATH
     iniset $CINDER_CONF DEFAULT periodic_interval $CINDER_PERIODIC_INTERVAL
 
+    if is_service_enabled swift; then
+        iniset $CINDER_CONF DEFAULT backup_swift_url "http://$SERVICE_HOST:8080/v1/AUTH_"
+    fi
+
     if is_service_enabled ceilometer; then
         iniset $CINDER_CONF DEFAULT notification_driver "cinder.openstack.common.notifier.rpc_notifier"
     fi
diff --git a/lib/cinder_plugins/nfs b/lib/cinder_plugins/nfs
index 2d9d875..5f4cc53 100644
--- a/lib/cinder_plugins/nfs
+++ b/lib/cinder_plugins/nfs
@@ -30,8 +30,7 @@
 function configure_cinder_driver {
     iniset $CINDER_CONF DEFAULT volume_driver "cinder.volume.drivers.nfs.NfsDriver"
     iniset $CINDER_CONF DEFAULT nfs_shares_config "$CINDER_CONF_DIR/nfs_shares.conf"
-    echo "$CINDER_NFS_SERVERPATH" | sudo tee "$CINDER_CONF_DIR/nfs_shares.conf"
-    sudo chmod 660 $CINDER_CONF_DIR/nfs_shares.conf
+    echo "$CINDER_NFS_SERVERPATH" | tee "$CINDER_CONF_DIR/nfs_shares.conf"
 }
 
 # Restore xtrace
diff --git a/lib/databases/mysql b/lib/databases/mysql
index 7a0145a..0a96cf8 100644
--- a/lib/databases/mysql
+++ b/lib/databases/mysql
@@ -83,36 +83,28 @@
 
     # Now update ``my.cnf`` for some local needs and restart the mysql service
 
-    # Change ‘bind-address’ from localhost (127.0.0.1) to any (0.0.0.0)
-    sudo sed -i '/^bind-address/s/127.0.0.1/0.0.0.0/g' $MY_CONF
+    # Change ‘bind-address’ from localhost (127.0.0.1) to any (0.0.0.0) and
+    # set default db type to InnoDB
+    sudo bash -c "source $TOP_DIR/functions && \
+        iniset $MY_CONF mysqld bind-address 0.0.0.0 && \
+        iniset $MY_CONF mysqld default-storage-engine InnoDB"
 
-    # Set default db type to InnoDB
-    if sudo grep -q "default-storage-engine" $MY_CONF; then
-        # Change it
-        sudo bash -c "source $TOP_DIR/functions; iniset $MY_CONF mysqld default-storage-engine InnoDB"
-    else
-        # Add it
-        sudo sed -i -e "/^\[mysqld\]/ a \
-default-storage-engine = InnoDB" $MY_CONF
-    fi
 
     if [[ "$DATABASE_QUERY_LOGGING" == "True" ]]; then
         echo_summary "Enabling MySQL query logging"
 
-        # Turn on slow query log
-        sudo sed -i '/log.slow.queries/d' $MY_CONF
-        sudo sed -i -e "/^\[mysqld\]/ a \
-            log-slow-queries = /var/log/mysql/mysql-slow.log" $MY_CONF
+        sudo sed -e '/log.slow.queries/d' \
+            -e '/long.query.time/d' \
+            -e '/log.queries.not.using.indexes/d' \
+            -i $MY_CONF
 
-        # Log all queries (any query taking longer than 0 seconds)
-        sudo sed -i '/long.query.time/d' $MY_CONF
-        sudo sed -i -e "/^\[mysqld\]/ a \
-            long-query-time = 0" $MY_CONF
-
-        # Log all non-indexed queries
-        sudo sed -i '/log.queries.not.using.indexes/d' $MY_CONF
-        sudo sed -i -e "/^\[mysqld\]/ a \
-            log-queries-not-using-indexes" $MY_CONF
+        # 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 /var/log/mysql/mysql-slow.log && \
+            iniset $MY_CONF mysqld long-query-time 0 && \
+            iniset $MY_CONF mysqld log-queries-not-using-indexes 1"
 
     fi
 
diff --git a/lib/heat b/lib/heat
index f66f0a8..fe75ec9 100644
--- a/lib/heat
+++ b/lib/heat
@@ -96,7 +96,7 @@
     iniset $HEAT_CONF DEFAULT heat_waitcondition_server_url http://$HEAT_API_CFN_HOST:$HEAT_API_CFN_PORT/v1/waitcondition
     iniset $HEAT_CONF DEFAULT heat_watch_server_url http://$HEAT_API_CW_HOST:$HEAT_API_CW_PORT
     iniset $HEAT_CONF database connection `database_connection_url heat`
-    iniset $HEAT_CONF DEFAULT auth_encryption_key `hexdump -n 16 -v -e '/1 "%02x"' /dev/random`
+    iniset $HEAT_CONF DEFAULT auth_encryption_key `hexdump -n 16 -v -e '/1 "%02x"' /dev/urandom`
 
     # logging
     iniset $HEAT_CONF DEFAULT debug $ENABLE_DEBUG_LOG_LEVEL
@@ -119,7 +119,6 @@
 
     # ec2authtoken
     iniset $HEAT_CONF ec2authtoken auth_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0
-    iniset $HEAT_CONF ec2authtoken keystone_ec2_uri $KEYSTONE_SERVICE_PROTOCOL://$KEYSTONE_SERVICE_HOST:$KEYSTONE_SERVICE_PORT/v2.0/ec2tokens
 
     # paste_deploy
     [[ "$HEAT_STANDALONE" = "True" ]] && iniset $HEAT_CONF paste_deploy flavor standalone
diff --git a/lib/horizon b/lib/horizon
index 27c2d26..90a2bc5 100644
--- a/lib/horizon
+++ b/lib/horizon
@@ -114,11 +114,9 @@
 
     local horizon_conf=/etc/$APACHE_NAME/$APACHE_CONF_DIR/horizon.conf
     if is_ubuntu; then
-        # 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
+        disable_apache_site 000-default
         sudo touch $horizon_conf
-        sudo a2ensite horizon.conf
+        enable_apache_site horizon.conf
     elif is_fedora; then
         sudo sed '/^Listen/s/^.*$/Listen 0.0.0.0:80/' -i /etc/httpd/conf/httpd.conf
     elif is_suse; then
diff --git a/lib/ironic b/lib/ironic
index 979420f..50c0fb6 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -42,6 +42,7 @@
 IRONIC_SCRIPTS_DIR=${IRONIC_SCRIPTS_DIR:-$TOP_DIR/tools/ironic/scripts}
 IRONIC_TEMPLATES_DIR=${IRONIC_TEMPLATES_DIR:-$TOP_DIR/tools/ironic/templates}
 IRONIC_BAREMETAL_BASIC_OPS=$(trueorfalse False $IRONIC_BAREMETAL_BASIC_OPS)
+IRONIC_DRIVERS_WHITELIST=${IRONIC_DRIVERS_WHITELIST:-fake,pxe_ssh}
 IRONIC_SSH_USERNAME=${IRONIC_SSH_USERNAME:-`whoami`}
 IRONIC_SSH_KEY_DIR=${IRONIC_SSH_KEY_DIR:-$IRONIC_DATA_DIR/ssh_keys}
 IRONIC_SSH_KEY_FILENAME=${IRONIC_SSH_KEY_FILENAME:-ironic_key}
@@ -171,6 +172,7 @@
     cp -r $IRONIC_DIR/etc/ironic/rootwrap.d $IRONIC_CONF_DIR
 
     iniset $IRONIC_CONF_FILE DEFAULT rootwrap_config $IRONIC_ROOTWRAP_CONF
+    iniset $IRONIC_CONF_FILE DEFAULT drivers_whitelist $IRONIC_DRIVERS_WHITELIST
     iniset $IRONIC_CONF_FILE conductor api_url http://$HOST_IP:6385
     iniset $IRONIC_CONF_FILE pxe tftp_server $HOST_IP
     iniset $IRONIC_CONF_FILE pxe tftp_root $IRONIC_TFTPBOOT_DIR
@@ -315,8 +317,13 @@
     IRONIC_NET_ID=$(neutron net-list | grep private | get_field 1)
     local idx=0
 
-    # work around; need to know what netns neutron uses for private network
-    neutron port-create private
+    # work around; need to know what netns neutron uses for private network.
+    # Without knowing how to interconnect the networks, PXE won't work properly
+    # for fake baremetal instances. The network should be configured prior all
+    # the instances operation. If we don't do this, the first port creation
+    # only happens in the middle of fake baremetal instance's spawning by nova,
+    # so we'll end up with unbootable fake baremetal VM due to broken PXE.
+    PORT_ID=$(neutron port-create private | grep " id " | get_field 2)
 
     while read MAC; do
 
@@ -357,6 +364,10 @@
 
     sudo ovs-vsctl -- --if-exists del-port ovs-tap1 -- add-port br-int ovs-tap1 tag=$TAG_ID
     sudo ovs-vsctl -- --if-exists del-port brbm-tap1 -- add-port $IRONIC_VM_NETWORK_BRIDGE brbm-tap1
+
+    # Remove the port needed only for workaround. For additional info read the
+    # comment at the beginning of this function
+    neutron port-delete $PORT_ID
 }
 
 function configure_tftpd {
@@ -496,19 +507,6 @@
         fi
     done
 
-    SCREEN_NAME=${SCREEN_NAME:-stack}
-    SERVICE_DIR=${SERVICE_DIR:-${DEST}/status}
-
-    # stop all nova services
-    stop_nova || true
-
-    # remove any nova services failure status
-    find $SERVICE_DIR/$SCREEN_NAME -name 'n-*.failure' -exec rm -f '{}' \;
-
-    # start them again
-    start_nova_api
-    start_nova
-
     TOKEN=$(keystone token-get | grep ' id ' | get_field 2)
     die_if_not_set $LINENO TOKEN "Keystone fail to get token"
 
@@ -520,6 +518,11 @@
     create_bridge_and_vms
     enroll_vms
     configure_tftpd
+
+    # restart nova-compute to ensure its resource tracking is up to
+    # date with newly enrolled nodes
+    stop_nova_compute || true
+    start_nova_compute
 }
 
 function cleanup_baremetal_basic_ops {
diff --git a/lib/neutron b/lib/neutron
index 294ffac..b7c9464 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -274,7 +274,7 @@
     if is_service_enabled q-fwaas; then
         _configure_neutron_fwaas
     fi
-    if is_service_enabled q-svc; then
+    if is_service_enabled q-agt q-svc; then
         _configure_neutron_service
     fi
     if is_service_enabled q-agt; then
@@ -765,7 +765,7 @@
     iniset $NEUTRON_CONF DEFAULT notify_nova_on_port_status_change $Q_NOTIFY_NOVA_PORT_STATUS_CHANGE
     iniset $NEUTRON_CONF DEFAULT notify_nova_on_port_data_changes $Q_NOTIFY_NOVA_ON_PORT_DATA_CHANGES
     iniset $NEUTRON_CONF DEFAULT nova_url "$NOVA_SERVICE_PROTOCOL://$NOVA_SERVICE_HOST:$NOVA_SERVICE_PORT/v2"
-    iniset $NEUTRON_CONF DEFAULT nova_admin_username nova $NOVA_USER
+    iniset $NEUTRON_CONF DEFAULT nova_admin_username nova
     iniset $NEUTRON_CONF DEFAULT nova_admin_password $SERVICE_PASSWORD
     ADMIN_TENANT_ID=$(openstack project list | awk "/ service / { print \$2 }")
     iniset $NEUTRON_CONF DEFAULT nova_admin_tenant_id $ADMIN_TENANT_ID
diff --git a/lib/neutron_plugins/ovs_base b/lib/neutron_plugins/ovs_base
index ae7f815..1e293a1 100644
--- a/lib/neutron_plugins/ovs_base
+++ b/lib/neutron_plugins/ovs_base
@@ -44,9 +44,8 @@
         # Ensure that the service is started
         restart_service openvswitch
     elif is_suse; then
-        install_package openvswitch
+        install_package openvswitch-switch
         restart_service openvswitch-switch
-        restart_service openvswitch-controller
     fi
 }
 
diff --git a/lib/nova b/lib/nova
index 5cc94ec..47e4afc 100644
--- a/lib/nova
+++ b/lib/nova
@@ -438,8 +438,8 @@
     iniset $NOVA_CONF DEFAULT instance_name_template "${INSTANCE_NAME_PREFIX}%08x"
     iniset $NOVA_CONF osapi_v3 enabled "True"
 
-    if is_fedora; then
-        # nova defaults to /usr/local/bin, but fedora pip likes to
+    if is_fedora || is_suse; then
+        # nova defaults to /usr/local/bin, but fedora and suse pip like to
         # install things in /usr/bin
         iniset $NOVA_CONF DEFAULT bindir "/usr/bin"
     fi
diff --git a/lib/opendaylight b/lib/opendaylight
index 1022e2c..be3db6e 100644
--- a/lib/opendaylight
+++ b/lib/opendaylight
@@ -35,6 +35,15 @@
 # ODL_MGR_IP=
 ODL_MGR_IP=${ODL_MGR_IP:-$SERVICE_HOST}
 
+# The ODL endpoint URL
+ODL_ENDPOINT=${ODL_ENDPOINT:-http://${ODL_MGR_IP}:8080/controller/nb/v2/neutron}
+
+# The ODL username
+ODL_USERNAME=${ODL_USERNAME:-admin}
+
+# The ODL password
+ODL_PASSWORD=${ODL_PASSWORD:-admin}
+
 # <define global variables here that belong to this project>
 ODL_DIR=$DEST/opendaylight
 
@@ -80,6 +89,12 @@
     echo "ovsdb.of.version=1.3" >> $ODL_DIR/opendaylight/configuration/config.ini
 }
 
+function configure_ml2_odl {
+    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_odl url=$ODL_ENDPOINT
+    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_odl username=$ODL_USERNAME
+    populate_ml2_config /$Q_PLUGIN_CONF_FILE ml2_odl password=$ODL_PASSWORD
+}
+
 # init_opendaylight() - Initialize databases, etc.
 function init_opendaylight {
     # clean up from previous (possibly aborted) runs
@@ -117,9 +132,8 @@
         # Ensure that the service is started
         restart_service openvswitch
     elif is_suse; then
-        install_package openvswitch
+        install_package openvswitch-switch
         restart_service openvswitch-switch
-        restart_service openvswitch-controller
     fi
 }
 
diff --git a/lib/sahara b/lib/sahara
index 1ff0cf9..cb86710 100644
--- a/lib/sahara
+++ b/lib/sahara
@@ -142,6 +142,11 @@
 
     iniset $SAHARA_CONF_FILE DEFAULT use_syslog $SYSLOG
 
+    # Format logging
+    if [ "$LOG_COLOR" == "True" ] && [ "$SYSLOG" == "False" ]; then
+        setup_colorized_logging $SAHARA_CONF_FILE DEFAULT
+    fi
+
     recreate_database sahara utf8
     $SAHARA_BIN_DIR/sahara-db-manage --config-file $SAHARA_CONF_FILE upgrade head
 }
diff --git a/lib/tempest b/lib/tempest
index 639a0d0..5122695 100644
--- a/lib/tempest
+++ b/lib/tempest
@@ -153,6 +153,7 @@
     # user and tenant are set up...
     ADMIN_USERNAME=${ADMIN_USERNAME:-admin}
     ADMIN_TENANT_NAME=${ADMIN_TENANT_NAME:-admin}
+    ADMIN_DOMAIN_NAME=${ADMIN_DOMAIN_NAME:-Default}
     TEMPEST_USERNAME=${TEMPEST_USERNAME:-demo}
     TEMPEST_TENANT_NAME=${TEMPEST_TENANT_NAME:-demo}
     ALT_USERNAME=${ALT_USERNAME:-alt_demo}
@@ -267,6 +268,7 @@
     iniset $TEMPEST_CONFIG identity admin_username $ADMIN_USERNAME
     iniset $TEMPEST_CONFIG identity admin_password "$password"
     iniset $TEMPEST_CONFIG identity admin_tenant_name $ADMIN_TENANT_NAME
+    iniset $TEMPEST_CONFIG identity admin_domain_name $ADMIN_DOMAIN_NAME
     iniset $TEMPEST_CONFIG identity auth_version ${TEMPEST_AUTH_VERSION:-v2}
 
     # Image
@@ -366,6 +368,11 @@
     # Networking
     iniset $TEMPEST_CONFIG network-feature-enabled api_extensions "${NETWORK_API_EXTENSIONS:-all}"
 
+    # Baremetal
+    if [ "$VIRT_DRIVER" = "ironic" ] ; then
+        iniset $TEMPEST_CONFIG baremetal driver_enabled True
+    fi
+
     # service_available
     for service in ${TEMPEST_SERVICES//,/ }; do
         if is_service_enabled $service ; then
@@ -425,9 +432,9 @@
         ( #new namespace
             # tenant:demo ; user: demo
             source $TOP_DIR/accrc/demo/demo
-            euca-bundle-image -i "$kernel" --kernel true -d "$BOTO_MATERIALS_PATH"
-            euca-bundle-image -i "$ramdisk" --ramdisk true -d "$BOTO_MATERIALS_PATH"
-            euca-bundle-image -i "$disk_image" -d "$BOTO_MATERIALS_PATH"
+            euca-bundle-image -r x86_64 -i "$kernel" --kernel true -d "$BOTO_MATERIALS_PATH"
+            euca-bundle-image -r x86_64 -i "$ramdisk" --ramdisk true -d "$BOTO_MATERIALS_PATH"
+            euca-bundle-image -r x86_64 -i "$disk_image" -d "$BOTO_MATERIALS_PATH"
         ) 2>&1 </dev/null | cat
     else
         echo "Boto materials are not prepared"
diff --git a/stack.sh b/stack.sh
index 91f188f..dff6bd3 100755
--- a/stack.sh
+++ b/stack.sh
@@ -149,6 +149,14 @@
     fi
 fi
 
+# Look for obsolete stuff
+if [[ ,${ENABLED_SERVICES} =~ ,"swift" ]]; then
+    echo "FATAL: 'swift' is not supported as a service name"
+    echo "FATAL: Use the actual swift service names to enable tham as required:"
+    echo "FATAL: s-proxy s-object s-container s-account"
+    exit 1
+fi
+
 # Make sure we only have one rpc backend enabled,
 # and the specified rpc backend is available on your platform.
 check_rpc_backend
@@ -215,21 +223,24 @@
     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-havana/rdo-release-havana.rpm"}
-    RHEL6_RDO_REPO_ID=${RHEL6_RDO_REPO_ID:-"openstack-havana"}
+if [[ is_fedora && $DISTRO =~ (rhel) ]]; then
+    # Installing Open vSwitch on RHEL requires enabling the RDO repo.
+    RHEL6_RDO_REPO_RPM=${RHEL6_RDO_REPO_RPM:-"http://rdo.fedorapeople.org/openstack-icehouse/rdo-release-icehouse.rpm"}
+    RHEL6_RDO_REPO_ID=${RHEL6_RDO_REPO_ID:-"openstack-icehouse"}
     if ! sudo 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"}
+    # RHEL requires EPEL for many Open Stack dependencies
+    if [[ $DISTRO =~ (rhel7) ]]; then
+        EPEL_RPM=${RHEL7_EPEL_RPM:-"http://dl.fedoraproject.org/pub/epel/beta/7/x86_64/epel-release-7-0.1.noarch.rpm"}
+    else
+        EPEL_RPM=${RHEL6_EPEL_RPM:-"http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm"}
+    fi
     if ! sudo yum repolist enabled epel | grep -q 'epel'; then
         echo "EPEL not detected; installing"
-        yum_install ${RHEL6_EPEL_RPM} || \
+        yum_install ${EPEL_RPM} || \
             die $LINENO "Error installing EPEL repo, cannot continue"
     fi
 
@@ -290,7 +301,7 @@
 
 HOST_IP=$(get_default_host_ip $FIXED_RANGE $FLOATING_RANGE "$HOST_IP_IFACE" "$HOST_IP")
 if [ "$HOST_IP" == "" ]; then
-    die $LINENO "Could not determine host ip address. Either localrc specified dhcp on ${HOST_IP_IFACE} or defaulted"
+    die $LINENO "Could not determine host ip address.  See local.conf for suggestions on setting HOST_IP."
 fi
 
 # Allow the use of an alternate hostname (such as localhost/127.0.0.1) for service endpoints.
@@ -425,7 +436,7 @@
 
 # Rabbit connection info
 if is_service_enabled rabbit; then
-    RABBIT_HOST=${RABBIT_HOST:-localhost}
+    RABBIT_HOST=${RABBIT_HOST:-$SERVICE_HOST}
     read_password RABBIT_PASSWORD "ENTER A PASSWORD TO USE FOR RABBIT."
 fi
 
@@ -1001,9 +1012,13 @@
     fi
 
     clean_iptables
-    rm -rf ${NOVA_STATE_PATH}/networks
-    sudo mkdir -p ${NOVA_STATE_PATH}/networks
-    safe_chown -R ${USER} ${NOVA_STATE_PATH}/networks
+
+    if is_service_enabled n-net; then
+        rm -rf ${NOVA_STATE_PATH}/networks
+        sudo mkdir -p ${NOVA_STATE_PATH}/networks
+        safe_chown -R ${USER} ${NOVA_STATE_PATH}/networks
+    fi
+
     # Force IP forwarding on, just in case
     sudo sysctl -w net.ipv4.ip_forward=1
 fi
diff --git a/stackrc b/stackrc
index 8320c9b..f6403cc 100644
--- a/stackrc
+++ b/stackrc
@@ -21,9 +21,9 @@
 
 # Specify which services to launch.  These generally correspond to
 # screen tabs. To change the default list, use the ``enable_service`` and
-# ``disable_service`` functions in ``localrc``.
-# For example, to enable Swift add this to ``localrc``:
-#  enable_service swift
+# ``disable_service`` functions in ``local.conf``.
+# For example, to enable Swift add this to ``local.conf``:
+#  enable_service s-proxy s-object s-container s-account
 # In order to enable Neutron (a single node setup) add the following
 # settings in `` localrc``:
 #  disable_service n-net
@@ -32,7 +32,6 @@
 #  enable_service q-dhcp
 #  enable_service q-l3
 #  enable_service q-meta
-#  enable_service neutron
 #  # Optional, to enable tempest configuration as part of devstack
 #  enable_service tempest
 
diff --git a/tools/build_docs.sh b/tools/build_docs.sh
index c566e63..384b1fa 100755
--- a/tools/build_docs.sh
+++ b/tools/build_docs.sh
@@ -22,7 +22,7 @@
 # --------
 
 # Source repo/branch for DevStack
-MASTER_REPO=${MASTER_REPO:-https://github.com/openstack-dev/devstack.git}
+MASTER_REPO=${MASTER_REPO:-git://git.openstack.org/openstack-dev/devstack}
 MASTER_BRANCH=${MASTER_BRANCH:-master}
 
 # http://devstack.org is a GitHub gh-pages site in the https://github.com/cloudbuilders/devtack.git repo
diff --git a/tools/image_list.sh b/tools/image_list.sh
new file mode 100755
index 0000000..fa6b92e
--- /dev/null
+++ b/tools/image_list.sh
@@ -0,0 +1,35 @@
+#!/bin/bash
+
+# Keep track of the devstack directory
+TOP_DIR=$(cd $(dirname "$0")/.. && pwd)
+
+source $TOP_DIR/functions
+
+# Possible virt drivers, if we have more, add them here. Always keep
+# dummy in the end position to trigger the fall through case.
+DRIVERS="openvz ironic libvirt vsphere xenserver dummy"
+
+# Extra variables to trigger getting additional images.
+ENABLED_SERVICES=h-api
+HEAT_FETCHED_TEST_IMAGE="Fedora-i386-20-20131211.1-sda"
+
+# Loop over all the virt drivers and collect all the possible images
+ALL_IMAGES=""
+for driver in $DRIVERS; do
+    VIRT_DRIVER=$driver
+    URLS=$(source $TOP_DIR/stackrc && echo $IMAGE_URLS)
+    if [[ ! -z "$ALL_IMAGES" ]]; then
+        ALL_IMAGES+=,
+    fi
+    ALL_IMAGES+=$URLS
+done
+
+# Make a nice list
+echo $ALL_IMAGES | tr ',' '\n' | sort | uniq
+
+# Sanity check - ensure we have a minimum number of images
+num=$(echo $ALL_IMAGES | tr ',' '\n' | sort | uniq | wc -l)
+if [[ "$num" -lt 5 ]]; then
+    echo "ERROR: We only found $num images in $ALL_IMAGES, which can't be right."
+    exit 1
+fi