Merge "make i local"
diff --git a/doc/source/guides/neutron.rst b/doc/source/guides/neutron.rst
index e99a143..5891f68 100644
--- a/doc/source/guides/neutron.rst
+++ b/doc/source/guides/neutron.rst
@@ -72,98 +72,6 @@
 
 
 
-
-
-Using Neutron with Multiple Interfaces
-======================================
-
-The first interface, eth0 is used for the OpenStack management (API,
-message bus, etc) as well as for ssh for an administrator to access
-the machine.
-
-::
-
-        stack@compute:~$ ifconfig eth0
-        eth0      Link encap:Ethernet  HWaddr bc:16:65:20:af:fc
-                  inet addr:192.168.1.18
-
-eth1 is manually configured at boot to not have an IP address.
-Consult your operating system documentation for the appropriate
-technique. For Ubuntu, the contents of `/etc/network/interfaces`
-contains:
-
-::
-
-        auto eth1
-        iface eth1 inet manual
-                up ifconfig $IFACE 0.0.0.0 up
-                down ifconfig $IFACE 0.0.0.0 down
-
-The second physical interface, eth1 is added to a bridge (in this case
-named br-ex), which is used to forward network traffic from guest VMs.
-Network traffic from eth1 on the compute nodes is then NAT'd by the
-controller node that runs Neutron's `neutron-l3-agent` and provides L3
-connectivity.
-
-::
-
-        stack@compute:~$ sudo ovs-vsctl add-br br-ex
-        stack@compute:~$ sudo ovs-vsctl add-port br-ex eth1
-        stack@compute:~$ sudo ovs-vsctl show
-        9a25c837-32ab-45f6-b9f2-1dd888abcf0f
-            Bridge br-ex
-                Port br-ex
-                    Interface br-ex
-                        type: internal
-                Port phy-br-ex
-                    Interface phy-br-ex
-                        type: patch
-                        options: {peer=int-br-ex}
-                Port "eth1"
-                    Interface "eth1"
-
-
-
-
-
-Neutron Networking with Open vSwitch
-====================================
-
-Configuring neutron, OpenStack Networking in DevStack is very similar to
-configuring `nova-network` - many of the same configuration variables
-(like `FIXED_RANGE` and `FLOATING_RANGE`) used by `nova-network` are
-used by neutron, which is intentional.
-
-The only difference is the disabling of `nova-network` in your
-local.conf, and the enabling of the neutron components.
-
-
-Configuration
--------------
-
-::
-
-        FIXED_RANGE=10.0.0.0/24
-        FLOATING_RANGE=192.168.27.0/24
-        PUBLIC_NETWORK_GATEWAY=192.168.27.2
-
-        disable_service n-net
-        enable_service q-svc
-        enable_service q-agt
-        enable_service q-dhcp
-        enable_service q-meta
-        enable_service q-l3
-
-        Q_USE_SECGROUP=True
-        ENABLE_TENANT_VLANS=True
-        TENANT_VLAN_RANGE=1000:1999
-        PHYSICAL_NETWORK=default
-        OVS_PHYSICAL_BRIDGE=br-ex
-
-In this configuration we are defining FLOATING_RANGE to be a
-subnet that exists in the private RFC1918 address space - however in
-in a real setup FLOATING_RANGE would be a public IP address range.
-
 Neutron Networking with Open vSwitch and Provider Networks
 ==========================================================
 
@@ -206,6 +114,48 @@
         }
 
 
+On a compute node, the first interface, eth0 is used for the OpenStack
+management (API, message bus, etc) as well as for ssh for an
+administrator to access the machine.
+
+::
+
+        stack@compute:~$ ifconfig eth0
+        eth0      Link encap:Ethernet  HWaddr bc:16:65:20:af:fc
+                  inet addr:10.0.0.3
+
+eth1 is manually configured at boot to not have an IP address.
+Consult your operating system documentation for the appropriate
+technique. For Ubuntu, the contents of `/etc/network/interfaces`
+contains:
+
+::
+
+        auto eth1
+        iface eth1 inet manual
+                up ifconfig $IFACE 0.0.0.0 up
+                down ifconfig $IFACE 0.0.0.0 down
+
+The second physical interface, eth1 is added to a bridge (in this case
+named br-ex), which is used to forward network traffic from guest VMs.
+
+::
+
+        stack@compute:~$ sudo ovs-vsctl add-br br-ex
+        stack@compute:~$ sudo ovs-vsctl add-port br-ex eth1
+        stack@compute:~$ sudo ovs-vsctl show
+        9a25c837-32ab-45f6-b9f2-1dd888abcf0f
+            Bridge br-ex
+                Port br-ex
+                    Interface br-ex
+                        type: internal
+                Port phy-br-ex
+                    Interface phy-br-ex
+                        type: patch
+                        options: {peer=int-br-ex}
+                Port "eth1"
+                    Interface "eth1"
+
 
 Service Configuration
 ---------------------
diff --git a/functions-common b/functions-common
index 3e5b3c2..6b9a861 100644
--- a/functions-common
+++ b/functions-common
@@ -976,12 +976,18 @@
     local sudo="sudo"
     [[ "$(id -u)" = "0" ]] && sudo="env"
 
+    # time all the apt operations
+    time_start "apt-get"
+
     $xtrace
 
     $sudo DEBIAN_FRONTEND=noninteractive \
         http_proxy=${http_proxy:-} https_proxy=${https_proxy:-} \
         no_proxy=${no_proxy:-} \
         apt-get --option "Dpkg::Options::=--force-confold" --assume-yes "$@"
+
+    # stop the clock
+    time_stop "apt-get"
 }
 
 function _parse_package_files {
@@ -2115,6 +2121,70 @@
     fi
 }
 
+# Timing infrastructure - figure out where large blocks of time are
+# used in DevStack
+#
+# The timing infrastructure for DevStack is about collecting buckets
+# of time that are spend in some subtask. For instance, that might be
+# 'apt', 'pip', 'osc', even database migrations. We do this by a pair
+# of functions: time_start / time_stop.
+#
+# These take a single parameter: $name - which specifies the name of
+# the bucket to be accounted against. time_totals function spits out
+# the results.
+#
+# Resolution is only in whole seconds, so should be used for long
+# running activities.
+
+declare -A TOTAL_TIME
+declare -A START_TIME
+
+# time_start $name
+#
+# starts the clock for a timer by name. Errors if that clock is
+# already started.
+function time_start {
+    local name=$1
+    local start_time=${START_TIME[$name]}
+    if [[ -n "$start_time" ]]; then
+        die $LINENO "Trying to start the clock on $name, but it's already been started"
+    fi
+    START_TIME[$name]=$(date +%s)
+}
+
+# time_stop $name
+#
+# stops the clock for a timer by name, and accumulate that time in the
+# global counter for that name. Errors if that clock had not
+# previously been started.
+function time_stop {
+    local name=$1
+    local start_time=${START_TIME[$name]}
+    if [[ -z "$start_time" ]]; then
+        die $LINENO "Trying to stop the clock on $name, but it was never started"
+    fi
+    local end_time=$(date +%s)
+    local elapsed_time=$(($end_time - $start_time))
+    local total=${TOTAL_TIME[$name]:-0}
+    # reset the clock so we can start it in the future
+    START_TIME[$name]=""
+    TOTAL_TIME[$name]=$(($total + $elapsed_time))
+}
+
+# time_totals
+#
+# prints out total time
+function time_totals {
+    echo
+    echo "========================"
+    echo "DevStack Components Timed"
+    echo "========================"
+    echo
+    for t in ${!TOTAL_TIME[*]}; do
+        local v=${TOTAL_TIME[$t]}
+        echo "$t - $v secs"
+    done
+}
 
 # Restore xtrace
 $XTRACE
diff --git a/inc/python b/inc/python
index fe7bba6..7d026c5 100644
--- a/inc/python
+++ b/inc/python
@@ -80,6 +80,8 @@
         return
     fi
 
+    time_start "pip_install"
+
     PIP_UPGRADE=$(trueorfalse False PIP_UPGRADE)
     if [[ "$PIP_UPGRADE" = "True" ]] ; then
         upgrade="--upgrade"
@@ -137,6 +139,8 @@
             $cmd_pip $upgrade \
             -r $test_req
     fi
+
+    time_stop "pip_install"
 }
 
 # get version of a package from global requirements file
diff --git a/stack.sh b/stack.sh
index b65c558..1976dff 100755
--- a/stack.sh
+++ b/stack.sh
@@ -1366,6 +1366,8 @@
     exec 1>&3
 fi
 
+# Dump out the time totals
+time_totals
 
 # Using the cloud
 # ===============