Add tools/install_pip.sh

Install a known working recent version of pip that handles installation
dependencies more correctly than before.  Extract to a separate script
so it can be used apart from stack.sh.

* Install distro setuptools if it not already present
* Install pip from source tarball as get-pip.py proved to be unreliable
* Remove python-distribute and python-pip from all prereq files,
  move python-setuptools to 'general'
* Remove the earlier unfubar_setuptppls() call that attenpted to fix this
* Only update requirements.txt when no changes in repo

Tested on Precise, F18 and CentOS6.
* Fedora and RHEL allow pip to install packages ON TOP OF RPM-installed
  packages.  THIS IS BROKEN.  And is one reason we have to be so picky
  about order and so forth.

Change-Id: Ibb4b42119dc2e51577c77bbbbffb110863e5324d
diff --git a/files/apts/general b/files/apts/general
index fdf8e20..fcf0b5b 100644
--- a/files/apts/general
+++ b/files/apts/general
@@ -1,6 +1,6 @@
 bridge-utils
 pylint
-python-pip
+python-setuptools
 screen
 unzip
 wget
diff --git a/files/apts/keystone b/files/apts/keystone
index c98409f..564921b 100644
--- a/files/apts/keystone
+++ b/files/apts/keystone
@@ -1,4 +1,3 @@
-python-setuptools
 python-dev
 python-lxml
 python-pastescript
diff --git a/files/apts/ryu b/files/apts/ryu
index 4a4fc52..e8ed926 100644
--- a/files/apts/ryu
+++ b/files/apts/ryu
@@ -1,4 +1,3 @@
-python-setuptools
 python-gevent
 python-gflags
 python-netifaces
diff --git a/files/apts/swift b/files/apts/swift
index 1c283cf..37d5bc0 100644
--- a/files/apts/swift
+++ b/files/apts/swift
@@ -10,7 +10,6 @@
 python-netifaces
 python-nose
 python-pastedeploy
-python-setuptools
 python-simplejson
 python-webob
 python-xattr
diff --git a/files/rpms-suse/general b/files/rpms-suse/general
index f28267c..355af88 100644
--- a/files/rpms-suse/general
+++ b/files/rpms-suse/general
@@ -6,8 +6,8 @@
 openssh
 openssl
 psmisc
+python-setuptools # instead of python-distribute; dist:sle11sp2
 python-cmd2 # dist:opensuse-12.3
-python-pip
 python-pylint
 python-unittest2
 python-virtualenv
diff --git a/files/rpms-suse/keystone b/files/rpms-suse/keystone
index 7d9a7bf..403d82f 100644
--- a/files/rpms-suse/keystone
+++ b/files/rpms-suse/keystone
@@ -7,8 +7,6 @@
 python-SQLAlchemy
 python-WebOb
 python-devel
-python-distribute
-python-setuptools # instead of python-distribute; dist:sle11sp2
 python-greenlet
 python-lxml
 python-mysql
diff --git a/files/rpms-suse/ryu b/files/rpms-suse/ryu
index 90b43a4..3797b6c 100644
--- a/files/rpms-suse/ryu
+++ b/files/rpms-suse/ryu
@@ -1,5 +1,3 @@
-python-distribute
-python-setuptools # instead of python-distribute; dist:sle11sp2
 python-Sphinx
 python-gevent
 python-netifaces
diff --git a/files/rpms-suse/swift b/files/rpms-suse/swift
index db379bb..f3c95aa 100644
--- a/files/rpms-suse/swift
+++ b/files/rpms-suse/swift
@@ -6,8 +6,6 @@
 python-configobj
 python-coverage
 python-devel
-python-distribute
-python-setuptools # instead of python-distribute; dist:sle11sp2
 python-eventlet
 python-greenlet
 python-netifaces
diff --git a/files/rpms/general b/files/rpms/general
index 9fa305c..2db31d1 100644
--- a/files/rpms/general
+++ b/files/rpms/general
@@ -11,7 +11,7 @@
 libxslt-devel # dist:rhel6 [2]
 psmisc
 pylint
-python-pip
+python-setuptools
 python-prettytable # dist:rhel6 [1]
 python-unittest2
 python-virtualenv
diff --git a/files/rpms/keystone b/files/rpms/keystone
index 33a4f47..52dbf47 100644
--- a/files/rpms/keystone
+++ b/files/rpms/keystone
@@ -4,10 +4,9 @@
 python-paste-deploy #dist:f16,f17,f18,f19
 python-paste-script #dist:f16,f17,f18,f19
 python-routes
-python-setuptools   #dist:f16,f17,f18,f19
 python-sqlalchemy
 python-sqlite2
 python-webob
 sqlite
 
-# Deps installed via pip for RHEL
\ No newline at end of file
+# Deps installed via pip for RHEL
diff --git a/files/rpms/ryu b/files/rpms/ryu
index 0f62f9f..e8ed926 100644
--- a/files/rpms/ryu
+++ b/files/rpms/ryu
@@ -1,5 +1,4 @@
 python-gevent
 python-gflags
 python-netifaces
-python-setuptools #dist:f16,f17,f18,f19
 python-sphinx
diff --git a/files/rpms/swift b/files/rpms/swift
index 2cc4a0b..b137f30 100644
--- a/files/rpms/swift
+++ b/files/rpms/swift
@@ -10,7 +10,6 @@
 python-netifaces
 python-nose
 python-paste-deploy # dist:f16,f17,f18,f19
-python-setuptools   # dist:f16,f17,f18,f19
 python-simplejson
 python-webob
 pyxattr
diff --git a/functions b/functions
index fe37e4c..14ed180 100644
--- a/functions
+++ b/functions
@@ -1140,8 +1140,11 @@
 
     echo "cd $REQUIREMENTS_DIR; $SUDO_CMD python update.py $project_dir"
 
-    (cd $REQUIREMENTS_DIR; \
-        $SUDO_CMD python update.py $project_dir)
+    # Don't update repo if local changes exist
+    if (cd $project_dir && git diff --quiet); then
+        (cd $REQUIREMENTS_DIR; \
+            $SUDO_CMD python update.py $project_dir)
+    fi
 
     pip_install -e $project_dir
     # ensure that further actions can do things like setup.py sdist
diff --git a/stack.sh b/stack.sh
index c2e6fe4..36f427f 100755
--- a/stack.sh
+++ b/stack.sh
@@ -578,18 +578,8 @@
 echo_summary "Installing package prerequisites"
 source $TOP_DIR/tools/install_prereqs.sh
 
-install_rpc_backend
-
-if is_service_enabled $DATABASE_BACKENDS; then
-    install_database
-fi
-
-if is_service_enabled neutron; then
-    install_neutron_agent_packages
-fi
-
-# Unbreak the giant mess that is the current state of setuptools
-unfubar_setuptools
+# Configure an appropriate python environment
+$TOP_DIR/tools/install_pip.sh
 
 # System-specific preconfigure
 # ============================
@@ -642,6 +632,16 @@
     sudo ln -sf /usr/bin/nosetests1.1 /usr/local/bin/nosetests
 fi
 
+install_rpc_backend
+
+if is_service_enabled $DATABASE_BACKENDS; then
+    install_database
+fi
+
+if is_service_enabled neutron; then
+    install_neutron_agent_packages
+fi
+
 TRACK_DEPENDS=${TRACK_DEPENDS:-False}
 
 # Install python packages into a virtualenv so that we can track them
diff --git a/tools/install_pip.sh b/tools/install_pip.sh
new file mode 100755
index 0000000..0ea8f53
--- /dev/null
+++ b/tools/install_pip.sh
@@ -0,0 +1,118 @@
+#!/usr/bin/env bash
+
+# **install_pip.sh**
+
+# install_pip.sh [--pip-version <version>] [--use-get-pip] [--setuptools] [--force]
+#
+# Update pip and friends to a known common version
+
+# Assumptions:
+# - currently we try to leave the system setuptools alone, install
+#   the system package if it is not already present
+# - update pip to $INSTALL_PIP_VERSION
+
+# Keep track of the current directory
+TOOLS_DIR=$(cd $(dirname "$0") && pwd)
+TOP_DIR=`cd $TOOLS_DIR/..; pwd`
+
+# Change dir to top of devstack
+cd $TOP_DIR
+
+# Import common functions
+source $TOP_DIR/functions
+
+FILES=$TOP_DIR/files
+
+# Handle arguments
+
+INSTALL_PIP_VERSION=${INSTALL_PIP_VERSION:-"1.4"}
+while [[ -n "$1" ]]; do
+    case $1 in
+        --force)
+            FORCE=1
+            ;;
+        --pip-version)
+            INSTALL_PIP_VERSION="$2"
+            shift
+            ;;
+        --setuptools)
+            SETUPTOOLS=1
+            ;;
+        --use-get-pip)
+            USE_GET_PIP=1;
+            ;;
+    esac
+    shift
+done
+
+SETUPTOOLS_EZ_SETUP_URL=https://bitbucket.org/pypa/setuptools/raw/bootstrap/ez_setup.py
+PIP_GET_PIP_URL=https://raw.github.com/pypa/pip/master/contrib/get-pip.py
+PIP_TAR_URL=https://pypi.python.org/packages/source/p/pip/pip-$INSTALL_PIP_VERSION.tar.gz
+
+GetDistro
+echo "Distro: $DISTRO"
+
+function get_versions() {
+    PIP=$(which pip 2>/dev/null || which pip-python 2>/dev/null)
+    if [[ -n $PIP ]]; then
+        DISTRIBUTE_VERSION=$($PIP freeze | grep 'distribute==')
+        SETUPTOOLS_VERSION=$($PIP freeze | grep 'setuptools==')
+        PIP_VERSION=$($PIP --version | awk '{ print $2}')
+        echo "pip: $PIP_VERSION  setuptools: $SETUPTOOLS_VERSION  distribute: $DISTRIBUTE_VERSION"
+    fi
+}
+
+function setuptools_ez_setup() {
+    if [[ ! -r $FILES/ez_setup.py ]]; then
+        (cd $FILES; \
+         curl -OR $SETUPTOOLS_EZ_SETUP_URL; \
+        )
+    fi
+    sudo python $FILES/ez_setup.py
+}
+
+function install_get_pip() {
+    if [[ ! -r $FILES/get-pip.py ]]; then
+        (cd $FILES; \
+            curl $PIP_GET_PIP_URL; \
+        )
+    fi
+    sudo python $FILES/get-pip.py
+}
+
+function install_pip_tarball() {
+    curl -O $PIP_TAR_URL
+    tar xvfz pip-$INSTALL_PIP_VERSION.tar.gz
+    cd pip-$INSTALL_PIP_VERSION
+    sudo python setup.py install
+}
+
+# Show starting versions
+get_versions
+
+# Do setuptools
+if [[ -n "$SETUPTOOLS" ]]; then
+    # We want it from source
+    uninstall_package python-setuptools
+    setuptools_ez_setup
+else
+    # See about installing the distro setuptools
+    if ! python -c "import setuptools"; then
+        install_package python-setuptools
+    fi
+fi
+
+# Do pip
+if [[ -z $PIP || "$PIP_VERSION" != "$INSTALL_PIP_VERSION" || -n $FORCE ]]; then
+
+    # Eradicate any and all system packages
+    uninstall_package python-pip
+
+    if [[ -n "$USE_GET_PIP" ]]; then
+        install_get_pip
+    else
+        install_pip_tarball
+    fi
+
+    get_versions
+fi