Browse code

Use unique build dir for pip installs

There is a bug in pip [1] where it will choose to install a package
from an existing build-dir if it exists over the version actually
requested.

Thus if a prior component has installed a later version of the
package, the unpacked code is already in /tmp/$USER-pip-build; it gets
re-installed and manifests in a confusing error along the lines of

---
Downloading/unpacking requests>=1.1,<1.2.3
(from -r /home/stack//python-cinderclient/requirements.txt (line 5))
Running setup.py egg_info for package requests
Requested requests>=1.1,<1.2.3 (from -r
/home/stack/python-cinderclient/requirements.txt (line 5)),
but installing version 1.2.3
...
error: Installed distribution requests 1.2.3 conflicts with
requirement requests>=1.1,<1.2.3
---

I believe pip 1.4 fixes this problem, but it should always be safe to
specify a unique build-directory for pip installs to avoid picking up
old versions.

We also add a cleanup_tmp function for clearing out anything that
stack.sh might leave around when un-stacking, and add a catch-all for
the pip-build dir.

[1] https://github.com/pypa/pip/issues/709

Change-Id: I7ce919cddfd6d6175ae67bd864f82e256ebc7090

Ian Wienand authored on 2013/07/16 12:36:34
Showing 2 changed files
... ...
@@ -913,14 +913,35 @@ function pip_install {
913 913
         PIP_MIRROR_OPT="--use-mirrors"
914 914
     fi
915 915
 
916
+    # pip < 1.4 has a bug where it will use an already existing build
917
+    # directory unconditionally.  Say an earlier component installs
918
+    # foo v1.1; pip will have built foo's source in
919
+    # /tmp/$USER-pip-build.  Even if a later component specifies foo <
920
+    # 1.1, the existing extracted build will be used and cause
921
+    # confusing errors.  By creating unique build directories we avoid
922
+    # this problem. See
923
+    #  https://github.com/pypa/pip/issues/709
924
+    local pip_build_tmp=$(mktemp --tmpdir -d pip-build.XXXXX)
925
+
916 926
     $SUDO_PIP PIP_DOWNLOAD_CACHE=${PIP_DOWNLOAD_CACHE:-/var/cache/pip} \
917 927
         HTTP_PROXY=$http_proxy \
918 928
         HTTPS_PROXY=$https_proxy \
919 929
         NO_PROXY=$no_proxy \
920
-        $CMD_PIP install $PIP_MIRROR_OPT $@
930
+        $CMD_PIP install --build=${pip_build_tmp} \
931
+        $PIP_MIRROR_OPT $@ \
932
+        && $SUDO_PIP rm -rf ${pip_build_tmp}
921 933
 }
922 934
 
923 935
 
936
+# Cleanup anything from /tmp on unstack
937
+# clean_tmp
938
+function cleanup_tmp {
939
+    local tmp_dir=${TMPDIR:-/tmp}
940
+
941
+    # see comments in pip_install
942
+    sudo rm -rf ${tmp_dir}/pip-build.*
943
+}
944
+
924 945
 # Service wrapper to restart services
925 946
 # restart_service service-name
926 947
 function restart_service() {
... ...
@@ -111,3 +111,5 @@ if is_service_enabled neutron; then
111 111
     stop_neutron_third_party
112 112
     cleanup_neutron
113 113
 fi
114
+
115
+cleanup_tmp