Merge "Change Midonet vif driver to generic"
diff --git a/README.md b/README.md
index 99e9838..6dc9ecd 100644
--- a/README.md
+++ b/README.md
@@ -34,7 +34,7 @@
 
 # Start A Dev Cloud
 
-Installing in a dedicated disposable vm is safer than installing on your dev machine!  To start a dev cloud:
+Installing in a dedicated disposable vm is safer than installing on your dev machine!  Plus you can pick one of the supported Linux distros for your VM.  To start a dev cloud run the following NOT AS ROOT (see below for more):
 
     ./stack.sh
 
@@ -57,6 +57,12 @@
     # list instances using ec2 api
     euca-describe-instances
 
+# DevStack Execution Environment
+
+DevStack runs rampant over the system it runs on, installing things and uninstalling other things.  Running this on a system you care about is a recipe for disappointment, or worse.  Alas, we're all in the virtualization business here, so run it in a VM.  And take advantage of the snapshot capabilities of your hypervisor of choice to reduce testing cycle times.  You might even save enough time to write one more feature before the next feature freeze...
+
+``stack.sh`` needs to have root access for a lot of tasks, but it also needs to have not-root permissions for most of its work and for all of the OpenStack services.  So ``stack.sh`` specifically does not run if you are root. This is a recent change (Oct 2013) from the previous behaviour of automatically creating a ``stack`` user.  Automatically creating a user account is not always the right response to running as root, so that bit is now an explicit step using ``tools/create-stack-user.sh``.  Run that (as root!) if you do not want to just use your normal login here, which works perfectly fine.
+
 # Customizing
 
 You can override environment variables used in `stack.sh` by creating file name `localrc`.  It is likely that you will need to do this to tweak your networking configuration should you need to access your cloud from a different host.
diff --git a/files/rpms-suse/general b/files/rpms-suse/general
index c8c234e..98c2795 100644
--- a/files/rpms-suse/general
+++ b/files/rpms-suse/general
@@ -11,7 +11,6 @@
 python-cmd2 # dist:opensuse-12.3
 python-pylint
 python-unittest2
-python-virtualenv
 screen
 tar
 tcpdump
diff --git a/functions b/functions
index d9445fe..01e2dfc 100644
--- a/functions
+++ b/functions
@@ -926,7 +926,7 @@
     elif is_fedora; then
         sudo yum remove -y "$@"
     elif is_suse; then
-        sudo rpm -e "$@"
+        sudo zypper rm "$@"
     else
         exit_distro_not_supported "uninstalling packages"
     fi
@@ -1335,7 +1335,7 @@
             vmdk_net_adapter="${props[2]}"
         fi
 
-        glance --os-auth-token $token --os-image-url http://$GLANCE_HOSTPORT image-create --name "$IMAGE_NAME" --is-public=True --container-format bare --disk-format vmdk --property vmware-disktype="$vmdk_disktype" --property vmware_adaptertype="$vmdk_adapter_type" --property hw_vif_model="$vmdk_net_adapter" < "${IMAGE}"
+        glance --os-auth-token $token --os-image-url http://$GLANCE_HOSTPORT image-create --name "$IMAGE_NAME" --is-public=True --container-format bare --disk-format vmdk --property vmware_disktype="$vmdk_disktype" --property vmware_adaptertype="$vmdk_adapter_type" --property hw_vif_model="$vmdk_net_adapter" < "${IMAGE}"
         return
     fi
 
@@ -1484,7 +1484,7 @@
 function wait_for_service() {
     local timeout=$1
     local url=$2
-    timeout $timeout sh -c "while ! http_proxy= https_proxy= curl -s $url >/dev/null; do sleep 1; done"
+    timeout $timeout sh -c "while ! curl --noproxy '*' -s $url >/dev/null; do sleep 1; done"
 }
 
 
diff --git a/lib/glance b/lib/glance
index 7e69682..c6f11d0 100644
--- a/lib/glance
+++ b/lib/glance
@@ -193,7 +193,7 @@
     screen_it g-reg "cd $GLANCE_DIR; $GLANCE_BIN_DIR/glance-registry --config-file=$GLANCE_CONF_DIR/glance-registry.conf"
     screen_it g-api "cd $GLANCE_DIR; $GLANCE_BIN_DIR/glance-api --config-file=$GLANCE_CONF_DIR/glance-api.conf"
     echo "Waiting for g-api ($GLANCE_HOSTPORT) to start..."
-    if ! timeout $SERVICE_TIMEOUT sh -c "while ! http_proxy= wget -q -O- http://$GLANCE_HOSTPORT; do sleep 1; done"; then
+    if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- http://$GLANCE_HOSTPORT; do sleep 1; done"; then
       die $LINENO "g-api did not start"
     fi
 }
diff --git a/lib/ironic b/lib/ironic
index 072d2de..f3b4a72 100644
--- a/lib/ironic
+++ b/lib/ironic
@@ -194,7 +194,7 @@
 function start_ironic_api() {
     screen_it ir-api "cd $IRONIC_DIR; $IRONIC_BIN_DIR/ironic-api --config-file=$IRONIC_CONF_FILE"
     echo "Waiting for ir-api ($IRONIC_HOSTPORT) to start..."
-    if ! timeout $SERVICE_TIMEOUT sh -c "while ! http_proxy= wget -q -O- http://$IRONIC_HOSTPORT; do sleep 1; done"; then
+    if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- http://$IRONIC_HOSTPORT; do sleep 1; done"; then
       die $LINENO "ir-api did not start"
     fi
 }
diff --git a/lib/keystone b/lib/keystone
index 699b94a..c93a436 100755
--- a/lib/keystone
+++ b/lib/keystone
@@ -372,7 +372,7 @@
     fi
 
     echo "Waiting for keystone to start..."
-    if ! timeout $SERVICE_TIMEOUT sh -c "while ! http_proxy= curl -s http://$SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/ >/dev/null; do sleep 1; done"; then
+    if ! timeout $SERVICE_TIMEOUT sh -c "while ! curl --noproxy '*' -s http://$SERVICE_HOST:$service_port/v$IDENTITY_API_VERSION/ >/dev/null; do sleep 1; done"; then
       die $LINENO "keystone did not start"
     fi
 
diff --git a/lib/neutron b/lib/neutron
index b1f96fc..778717d 100644
--- a/lib/neutron
+++ b/lib/neutron
@@ -419,7 +419,7 @@
     # Start the Neutron service
     screen_it q-svc "cd $NEUTRON_DIR && python $NEUTRON_BIN_DIR/neutron-server $CFG_FILE_OPTIONS"
     echo "Waiting for Neutron to start..."
-    if ! timeout $SERVICE_TIMEOUT sh -c "while ! http_proxy= wget -q -O- http://$Q_HOST:$Q_PORT; do sleep 1; done"; then
+    if ! timeout $SERVICE_TIMEOUT sh -c "while ! wget --no-proxy -q -O- http://$Q_HOST:$Q_PORT; do sleep 1; done"; then
       die $LINENO "Neutron did not start"
     fi
 }
diff --git a/lib/nova b/lib/nova
index e5c78d8..99cd843 100644
--- a/lib/nova
+++ b/lib/nova
@@ -510,6 +510,7 @@
         iniset $NOVA_CONF DEFAULT instance_usage_audit "True"
         iniset $NOVA_CONF DEFAULT instance_usage_audit_period "hour"
         iniset $NOVA_CONF DEFAULT notify_on_state_change "vm_and_task_state"
+        iniset $NOVA_CONF DEFAULT notification_driver "nova.openstack.common.notifier.rpc_notifier"
     fi
 
     # Provide some transition from ``EXTRA_FLAGS`` to ``EXTRA_OPTS``
diff --git a/lib/swift b/lib/swift
index 9c80802..c0dec97 100644
--- a/lib/swift
+++ b/lib/swift
@@ -67,6 +67,10 @@
 # Default is ``staticweb, tempurl, formpost``
 SWIFT_EXTRAS_MIDDLEWARE=${SWIFT_EXTRAS_MIDDLEWARE:-tempurl formpost staticweb}
 
+# Set ``SWIFT_EXTRAS_MIDDLEWARE_LAST`` to extras middlewares that need to be at
+# the end of the pipeline.
+SWIFT_EXTRAS_MIDDLEWARE_LAST=${SWIFT_EXTRAS_MIDDLEWARE_LAST}
+
 # The ring uses a configurable number of bits from a path’s MD5 hash as
 # a partition index that designates a device. The number of bits kept
 # from the hash is known as the partition power, and 2 to the partition
@@ -255,6 +259,12 @@
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port
     iniset ${SWIFT_CONFIG_PROXY_SERVER} DEFAULT bind_port ${SWIFT_DEFAULT_BIND_PORT:-8080}
 
+    # Configure Ceilometer
+    if is_service_enabled ceilometer; then
+        iniset ${SWIFT_CONFIG_PROXY_SERVER} filter:ceilometer use "egg:ceilometer#swift"
+        SWIFT_EXTRAS_MIDDLEWARE_LAST="${SWIFT_EXTRAS_MIDDLEWARE_LAST} ceilometer"
+    fi
+
     # By default Swift will be installed with keystone and tempauth middleware
     # and add the swift3 middleware if its configured for it. The token for
     # tempauth would be prefixed with the reseller_prefix setting TEMPAUTH_ the
@@ -264,6 +274,7 @@
     fi
     swift_pipeline+=" authtoken keystoneauth tempauth "
     sed -i "/^pipeline/ { s/tempauth/${swift_pipeline} ${SWIFT_EXTRAS_MIDDLEWARE}/ ;}" ${SWIFT_CONFIG_PROXY_SERVER}
+    sed -i "/^pipeline/ { s/proxy-server/${SWIFT_EXTRAS_MIDDLEWARE_LAST} proxy-server/ ; }" ${SWIFT_CONFIG_PROXY_SERVER}
 
     iniuncomment ${SWIFT_CONFIG_PROXY_SERVER} filter:tempauth account_autocreate
     iniset ${SWIFT_CONFIG_PROXY_SERVER} app:proxy-server account_autocreate true
diff --git a/stack.sh b/stack.sh
index b39cd73..86fe82a 100755
--- a/stack.sh
+++ b/stack.sh
@@ -172,67 +172,37 @@
 # -----------
 
 # OpenStack is designed to be run as a non-root user; Horizon will fail to run
-# as **root** since Apache will not serve content from **root** user).  If
-# ``stack.sh`` is run as **root**, it automatically creates a **stack** user with
-# sudo privileges and runs as that user.
+# as **root** since Apache will not serve content from **root** user).
+# ``stack.sh`` must not be run as **root**.  It aborts and suggests one course of
+# action to create a suitable user account.
 
 if [[ $EUID -eq 0 ]]; then
-    ROOTSLEEP=${ROOTSLEEP:-10}
     echo "You are running this script as root."
-    echo "In $ROOTSLEEP seconds, we will create a user '$STACK_USER' and run as that user"
-    sleep $ROOTSLEEP
-
-    # Give the non-root user the ability to run as **root** via ``sudo``
-    is_package_installed sudo || install_package sudo
-    if ! getent group $STACK_USER >/dev/null; then
-        echo "Creating a group called $STACK_USER"
-        groupadd $STACK_USER
-    fi
-    if ! getent passwd $STACK_USER >/dev/null; then
-        echo "Creating a user called $STACK_USER"
-        useradd -g $STACK_USER -s /bin/bash -d $DEST -m $STACK_USER
-    fi
-
-    echo "Giving stack user passwordless sudo privileges"
-    # UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one
-    grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
-        echo "#includedir /etc/sudoers.d" >> /etc/sudoers
-    ( umask 226 && echo "$STACK_USER ALL=(ALL) NOPASSWD:ALL" \
-        > /etc/sudoers.d/50_stack_sh )
-
-    STACK_DIR="$DEST/${TOP_DIR##*/}"
-    echo "Copying files to $STACK_DIR"
-    cp -r -f -T "$TOP_DIR" "$STACK_DIR"
-    safe_chown -R $STACK_USER "$STACK_DIR"
-    cd "$STACK_DIR"
-    if [[ "$SHELL_AFTER_RUN" != "no" ]]; then
-        exec sudo -u $STACK_USER  bash -l -c "set -e; bash stack.sh; bash"
-    else
-        exec sudo -u $STACK_USER bash -l -c "set -e; source stack.sh"
-    fi
+    echo "Cut it out."
+    echo "Really."
+    echo "If you need an account to run DevStack, do this (as root, heh) to create $STACK_USER:"
+    echo "$TOP_DIR/tools/create-stack-user.sh"
     exit 1
-else
-    # We're not **root**, make sure ``sudo`` is available
-    is_package_installed sudo || die "Sudo is required.  Re-run stack.sh as root ONE TIME ONLY to set up sudo."
-
-    # UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one
-    sudo grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
-        echo "#includedir /etc/sudoers.d" | sudo tee -a /etc/sudoers
-
-    # Set up devstack sudoers
-    TEMPFILE=`mktemp`
-    echo "$STACK_USER ALL=(root) NOPASSWD:ALL" >$TEMPFILE
-    # Some binaries might be under /sbin or /usr/sbin, so make sure sudo will
-    # see them by forcing PATH
-    echo "Defaults:$STACK_USER secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE
-    chmod 0440 $TEMPFILE
-    sudo chown root:root $TEMPFILE
-    sudo mv $TEMPFILE /etc/sudoers.d/50_stack_sh
-
-    # Remove old file
-    sudo rm -f /etc/sudoers.d/stack_sh_nova
 fi
 
+# We're not **root**, make sure ``sudo`` is available
+is_package_installed sudo || install_package sudo
+
+# UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one
+sudo grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
+    echo "#includedir /etc/sudoers.d" | sudo tee -a /etc/sudoers
+
+# Set up devstack sudoers
+TEMPFILE=`mktemp`
+echo "$STACK_USER ALL=(root) NOPASSWD:ALL" >$TEMPFILE
+# Some binaries might be under /sbin or /usr/sbin, so make sure sudo will
+# see them by forcing PATH
+echo "Defaults:$STACK_USER secure_path=/sbin:/usr/sbin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin" >> $TEMPFILE
+chmod 0440 $TEMPFILE
+sudo chown root:root $TEMPFILE
+sudo mv $TEMPFILE /etc/sudoers.d/50_stack_sh
+
+
 # Create the destination directory and ensure it is writable by the user
 # and read/executable by everybody for daemons (e.g. apache run for horizon)
 sudo mkdir -p $DEST
diff --git a/tools/create-stack-user.sh b/tools/create-stack-user.sh
new file mode 100644
index 0000000..2251d1e
--- /dev/null
+++ b/tools/create-stack-user.sh
@@ -0,0 +1,49 @@
+#!/usr/bin/env bash
+
+# **create-stack-user.sh**
+
+# Create a user account suitable for running DevStack
+# - create a group named $STACK_USER if it does not exist
+# - create a user named $STACK_USER if it does not exist
+#   - home is $DEST
+# - configure sudo for $STACK_USER
+
+# ``stack.sh`` was never intended to run as root.  It had a hack to do what is
+# now in this script and re-launch itself, but that hack was less than perfect
+# and it was time for this nonsense to stop.  Run this script as root to create
+# the user and configure sudo.
+
+
+# Keep track of the devstack directory
+TOP_DIR=$(cd $(dirname "$0")/.. && pwd)
+
+# Import common functions
+source $TOP_DIR/functions
+
+# Determine what system we are running on.  This provides ``os_VENDOR``,
+# ``os_RELEASE``, ``os_UPDATE``, ``os_PACKAGE``, ``os_CODENAME``
+# and ``DISTRO``
+GetDistro
+
+# Needed to get ``ENABLED_SERVICES``
+source $TOP_DIR/stackrc
+
+# Give the non-root user the ability to run as **root** via ``sudo``
+is_package_installed sudo || install_package sudo
+
+if ! getent group $STACK_USER >/dev/null; then
+    echo "Creating a group called $STACK_USER"
+    groupadd $STACK_USER
+fi
+
+if ! getent passwd $STACK_USER >/dev/null; then
+    echo "Creating a user called $STACK_USER"
+    useradd -g $STACK_USER -s /bin/bash -d $DEST -m $STACK_USER
+fi
+
+echo "Giving stack user passwordless sudo privileges"
+# UEC images ``/etc/sudoers`` does not have a ``#includedir``, add one
+grep -q "^#includedir.*/etc/sudoers.d" /etc/sudoers ||
+    echo "#includedir /etc/sudoers.d" >> /etc/sudoers
+( umask 226 && echo "$STACK_USER ALL=(ALL) NOPASSWD:ALL" \
+    > /etc/sudoers.d/50_stack_sh )
diff --git a/tools/create_userrc.sh b/tools/create_userrc.sh
index 619d63f..44b0f6b 100755
--- a/tools/create_userrc.sh
+++ b/tools/create_userrc.sh
@@ -6,6 +6,9 @@
 
 # Warning: This script just for development purposes
 
+set -o errexit
+set -o xtrace
+
 ACCOUNT_DIR=./accrc
 
 display_help()
@@ -138,10 +141,14 @@
 mkdir -p "$ACCOUNT_DIR"
 ACCOUNT_DIR=`readlink -f "$ACCOUNT_DIR"`
 EUCALYPTUS_CERT=$ACCOUNT_DIR/cacert.pem
-mv "$EUCALYPTUS_CERT" "$EUCALYPTUS_CERT.old" &>/dev/null
+if [ -e "$EUCALYPTUS_CERT" ]; then
+    mv "$EUCALYPTUS_CERT" "$EUCALYPTUS_CERT.old"
+fi
 if ! nova x509-get-root-cert "$EUCALYPTUS_CERT"; then
     echo "Failed to update the root certificate: $EUCALYPTUS_CERT" >&2
-    mv "$EUCALYPTUS_CERT.old" "$EUCALYPTUS_CERT" &>/dev/null
+    if [ -e "$EUCALYPTUS_CERT.old" ]; then
+        mv "$EUCALYPTUS_CERT.old" "$EUCALYPTUS_CERT"
+    fi
 fi
 
 
@@ -168,12 +175,20 @@
     local ec2_cert="$rcfile-cert.pem"
     local ec2_private_key="$rcfile-pk.pem"
     # Try to preserve the original file on fail (best effort)
-    mv -f "$ec2_private_key" "$ec2_private_key.old" &>/dev/null
-    mv -f "$ec2_cert" "$ec2_cert.old" &>/dev/null
+    if [ -e "$ec2_private_key" ]; then
+        mv -f "$ec2_private_key" "$ec2_private_key.old"
+    fi
+    if [ -e "$ec2_cert" ]; then
+        mv -f "$ec2_cert" "$ec2_cert.old"
+    fi
     # It will not create certs when the password is incorrect
     if ! nova --os-password "$user_passwd" --os-username "$user_name" --os-tenant-name "$tenant_name" x509-create-cert "$ec2_private_key" "$ec2_cert"; then
-        mv -f "$ec2_private_key.old" "$ec2_private_key" &>/dev/null
-        mv -f "$ec2_cert.old" "$ec2_cert" &>/dev/null
+        if [ -e "$ec2_private_key.old" ]; then
+            mv -f "$ec2_private_key.old" "$ec2_private_key"
+        fi
+        if [ -e "$ec2_cert.old" ]; then
+            mv -f "$ec2_cert.old" "$ec2_cert"
+        fi
     fi
     cat >"$rcfile" <<EOF
 # you can source this file
diff --git a/tools/fixup_stuff.sh b/tools/fixup_stuff.sh
index 87922c8..f3c0f98 100755
--- a/tools/fixup_stuff.sh
+++ b/tools/fixup_stuff.sh
@@ -16,6 +16,8 @@
 #   - pre-install hgtools to work around a bug in RHEL6 distribute
 #   - install nose 1.1 from EPEL
 
+set -o errexit
+set -o xtrace
 
 # Keep track of the current directory
 TOOLS_DIR=$(cd $(dirname "$0") && pwd)
diff --git a/tools/install_pip.sh b/tools/install_pip.sh
index fc1c195..04e1826 100755
--- a/tools/install_pip.sh
+++ b/tools/install_pip.sh
@@ -9,6 +9,9 @@
 # Assumptions:
 # - update pip to $INSTALL_PIP_VERSION
 
+set -o errexit
+set -o xtrace
+
 # Keep track of the current directory
 TOOLS_DIR=$(cd $(dirname "$0") && pwd)
 TOP_DIR=`cd $TOOLS_DIR/..; pwd`
diff --git a/unstack.sh b/unstack.sh
index 05d9fb7..c944ccc 100755
--- a/unstack.sh
+++ b/unstack.sh
@@ -24,6 +24,12 @@
 # Destination path for service data
 DATA_DIR=${DATA_DIR:-${DEST}/data}
 
+if [[ $EUID -eq 0 ]]; then
+    echo "You are running this script as root."
+    echo "It might work but you will have a better day running it as $STACK_USER"
+    exit 1
+fi
+
 # Import apache functions
 source $TOP_DIR/lib/apache