#!/bin/bash if [ ${DIB_DEBUG_TRACE:-0} -gt 0 ]; then set -x fi set -eu set -o pipefail if [[ $DISTRO_NAME =~ (opensuse|fedora|centos|centos7|rhel7) ]]; then # Default packages _do_py3=0 _extra_repo='' case "$DISTRO_NAME" in centos*|rhel7) # note python2-pip in epel _extra_repo="--enablerepo=epel" packages="python-virtualenv python2-pip" if [[ "$(rpm -q --qf '[%{obsoletes}\n]' python2-setuptools)" == "python-setuptools" ]]; then # If OpenStack release is installed, then python-setuptools is # obsoleted by python2-setuptools packages+=" python2-setuptools" else packages+=" python-setuptools" fi ;; fedora) _do_py3=1 packages="python2-virtualenv python2-pip python2-setuptools" packages+=" python3-virtualenv python3-pip python3-setuptools" ;; opensuse) case "$DIB_RELEASE" in 42*) packages="python-virtualenv python-pip python-setuptools" ;; tumbleweed|15*) # XXX: python3? packages="python2-virtualenv python2-pip python2-setuptools" ;; esac esac # force things to happen so our assumptions hold pip_args="-U --force-reinstall" # GENERAL WARNING : mixing packaged python libraries with # pip-installed versions always creates issues. Upstream # openstack-infra uses this a lot (especially devstack) but be # warned: here be dragons :) # Firstly we want to install the system packages. Otherwise later # on somebody does a "yum install python-virtualenv" and goes and # overwrites the pip installed version with the packaged version, # leading to all sorts of weird version issues. if [[ $DISTRO_NAME = opensuse ]]; then zypper -n install $packages else ${YUM:-yum} ${_extra_repo} install -y $packages fi # pip10 onwards (unlike earlier versions) will not uninstall # packages installed by distutils (note this is only a subset of # packages that don't use setuptools for various reasons; the # problem is essentially they do not include a manifest of files # in the package to delete, so pip was just guessing). We give it # a little help by clearing out the files from the packages we are # about to re-install so pip doesn't think anything is installed. # See: https://github.com/pypa/pip/issues/4805 # # This is only necessary on CentOS -- for complicated reasons of # course. On Fedora, the Python2 virtualenv packages are *not* # distutils based and pip overwrites them correctly. For python3, # pip has changed to not overwrite system packages (a long # standing difference between Debuntu and Fedora), but a number of # tools run with "python3 -Es" to isolate themselves to the # package installed versions. So we definitely don't want to # clear the packaged versions out in that case. if [[ $DISTRO_NAME == "centos" ]]; then for pkg in $packages; do rpm -ql $pkg | xargs rm -rf done fi # install the latest python2 pip; this overwrites packaged pip python /tmp/get-pip.py ${pip_args} # Install latest setuptools; there is a slight chicken-egg issue in # that pip requires setuptools for some operations like building a # wheel. But this simple install should be fine. pip install ${pip_args} setuptools if [[ $_do_py3 -eq 1 ]]; then # Repeat above for python3 # python2 on fedora always installs into /usr/bin. Move pip2 # binary out, as we want "pip" in the final image to be # python2 for historical reasons. mv /usr/bin/pip /usr/bin/pip2 # You would think that installing python3 bits first, then # python2 would work -- alas get-pip.py doesn't seem to leave # python3 alone: # https://github.com/pypa/pip/issues/4435 python3 /tmp/get-pip.py ${pip_args} pip3 install ${pip_args} setuptools # on < 27, this installed pip3 to /usr/bin/pip. On >=27 it's # /usr/local/bin/pip. reclaim /usr/bin/pip back to pip2 and # remove the /usr/local/bin/pip (i.e. python3 version) if it # exists, so that "pip" calls pip2 always. if we want pip3 we # call it explicitly. ln -sf /usr/bin/pip2 /usr/bin/pip rm -f /usr/local/bin/pip # So on Fedora, there are now supposed to be two versions of # python3 setuptools installed; the one installed by pip in # /usr/local and the one installed by the system # python3-setuptools rpm package in /usr/local. The idea is # that packaged python tools use the "system" python (with -Es # flag) and are isolated from pip installs ... except there is # an issue where pip clears out the RPM version files before # installing it's isolated version: # https://bugzilla.redhat.com/show_bug.cgi?id=1550368 # # Thus we need to *reinstall* the RPM version now, so those # files come back and system tools continue to work dnf reinstall -y python3-setuptools fi # now install latest virtualenv. it vendors stuff it needs so # doesn't have issues with other system packages. # python[2|3]-virtualenv package has installed versioned scripts # (/usr/bin/virtualenv-[2|3]) but upstream does not! (see [2]). # For consistency, reinstall so we're just left with python2's # version. Note this is a rather moot point, the usual way we get # a python3 environment is to call "virtualenv -p python3 foo" and # that works to create a python3 virtualenv, even if using # python2's version. Thus we probably don't *really* need to # "pip3 install virtualenv". What we don't want is "virtualenv # foo" creating a python3 virtualenv by default, because that # confuses a lot of legacy code. # #[2] http://pkgs.fedoraproject.org/cgit/rpms/python-virtualenv.git/tree/python-virtualenv.spec#n116) pip install ${pip_args} virtualenv mv /usr/bin/virtualenv /usr/bin/virtualenv2 if [[ $_do_py3 -eq 1 ]]; then pip3 install ${pip_args} virtualenv fi # Reclaim virtualenv to virtualenv2; similar to above, on fedora # >27 the pip3 version has gone into /usr/local/bin; remove it so # only /usr/bin/virtualenv exists ln -sf /usr/bin/virtualenv2 /usr/bin/virtualenv rm -f /usr/local/bin/virtualenv # at this point, we should have the latest # pip/setuptools/virtualenv packages for python2 & 3, and # "/usr/bin/pip" and "/usr/bin/virtualenv" should be python2 # versions. if [[ $DISTRO_NAME = opensuse ]]; then for pkg in virtualenv pip setuptools; do cat - >> /etc/zypp/locks <> ${conf} fi elif [[ $DISTRO_NAME = gentoo ]]; then packages="dev-python/pip dev-python/virtualenv" emerge -U $packages else # pre-install packages so dependencies are there. We will # overwrite with latest below. packages="python-pip python3-pip python-virtualenv" # Unfortunately older ubuntu (trusty) doesn't have a # python3-virtualenv package -- it seems it wasn't ready at the # time and you had to use "python -m venv". Since then virtualenv # has gained 3.4 support so the pip install below will work if [[ ${DIB_PYTHON_VERSION} == 3 ]]; then packages+=" python3-virtualenv" fi apt-get -y install $packages # force things to happen so our assumptions hold pip_args="-U --force-reinstall" # These install into /usr/local/bin so override any packages, even # if installed later. python3 /tmp/get-pip.py $pip_args python2 /tmp/get-pip.py $pip_args pip3 install $pip_args virtualenv pip install $pip_args virtualenv fi