From 08bbd16c52f943b34b0d8e7ca6b747935ad70007 Mon Sep 17 00:00:00 2001 From: Ian Wienand Date: Mon, 27 Apr 2020 14:57:12 +1000 Subject: [PATCH] Add ensure-virtualenv This is part of the efforts to remove pip-and-virtualenv from our base images [1]. There are some users who specifically require the virtualenv command (perhaps, like dib, they have some code that uses the activate_this.py mechanisms it provides wich venv does not). This installs the virtualenv package for the currently running distribution. One of the main maintenance issues of pip-and-virtualenv is that tried to ensure that "virtualenv" created a Python 2 environment always by default. Now that we have Python 3 only distributions like current Fedora, this is not something we can continue to do (even if we wanted to, which we don't). What owns virtualenv and what it produces in our heterogeneous environment is messy, and I think the best we can do is document it as done here. [1] https://docs.opendev.org/opendev/infra-specs/latest/specs/cleanup-test-node-python.html Change-Id: I97d8bfb970ed2b5aaa02a0813899014c94994066 --- doc/source/python-roles.rst | 1 + roles/ensure-virtualenv/README.rst | 28 +++++++++++++++++++++ roles/ensure-virtualenv/tasks/CentOS-7.yaml | 6 +++++ roles/ensure-virtualenv/tasks/Debian.yaml | 5 ++++ roles/ensure-virtualenv/tasks/Gentoo.yaml | 5 ++++ roles/ensure-virtualenv/tasks/RedHat.yaml | 6 +++++ roles/ensure-virtualenv/tasks/Suse.yaml | 4 +++ roles/ensure-virtualenv/tasks/default.yaml | 3 +++ roles/ensure-virtualenv/tasks/main.yaml | 18 +++++++++++++ test-playbooks/ensure-pip.yaml | 27 +++++++++++++++++--- zuul-tests.d/python-jobs.yaml | 1 + 11 files changed, 101 insertions(+), 3 deletions(-) create mode 100644 roles/ensure-virtualenv/README.rst create mode 100644 roles/ensure-virtualenv/tasks/CentOS-7.yaml create mode 100644 roles/ensure-virtualenv/tasks/Debian.yaml create mode 100644 roles/ensure-virtualenv/tasks/Gentoo.yaml create mode 100644 roles/ensure-virtualenv/tasks/RedHat.yaml create mode 100644 roles/ensure-virtualenv/tasks/Suse.yaml create mode 100644 roles/ensure-virtualenv/tasks/default.yaml create mode 100644 roles/ensure-virtualenv/tasks/main.yaml diff --git a/doc/source/python-roles.rst b/doc/source/python-roles.rst index b7d871e26..8089c2b2d 100644 --- a/doc/source/python-roles.rst +++ b/doc/source/python-roles.rst @@ -10,6 +10,7 @@ Python Roles .. zuul:autorole:: ensure-sphinx .. zuul:autorole:: ensure-tox .. zuul:autorole:: ensure-twine +.. zuul:autorole:: ensure-virtualenv .. zuul:autorole:: fetch-coverage-output .. zuul:autorole:: fetch-python-sdist-output .. zuul:autorole:: fetch-sphinx-output diff --git a/roles/ensure-virtualenv/README.rst b/roles/ensure-virtualenv/README.rst new file mode 100644 index 000000000..f3a64b0ae --- /dev/null +++ b/roles/ensure-virtualenv/README.rst @@ -0,0 +1,28 @@ +Ensure virtualenv is available + +This role installs the requirements for the ``virtualenv`` command +on the current distribution. + +Users should be aware of some portability issues when using +``virtualenv``: + +* Distributions differ on the interpreter that ``virtualenv`` is + provided by, so by calling ``virtualenv`` with no other arguments + means that on some platforms you will get a Python 2 environment and + others a Python 3 environment. +* If you wish to call ``virtualenv`` as a module (e.g. ``python -m + virtualenv``) you will need to know which interpreter owns the + ``virtualenv`` package for your distribution; e.g. on some, such as + Bionic, ``virtualenv`` is provided by ``python3-virtualenv`` but + ``python`` refers to Python 2, so ``python -m virtualenv`` is not a + portable way to call ``virtualenv``. +* ``virtualenv -p python3`` is likely the most portable way to + consistently get a Python 3 environment. ``virtualenv -p python2`` + may not work on some platforms without Python 2. +* If you use Python 3 and do not require the specific features of + ``virtualenv``, it is likely easier to use Python's inbuilt + ``python3 -m venv`` module to create an isolated environment. If + you are using ``pip:`` in your Ansible roles and require an + environment, see the documentation for :zuul:role:`ensure-pip`. + + diff --git a/roles/ensure-virtualenv/tasks/CentOS-7.yaml b/roles/ensure-virtualenv/tasks/CentOS-7.yaml new file mode 100644 index 000000000..602c2ce25 --- /dev/null +++ b/roles/ensure-virtualenv/tasks/CentOS-7.yaml @@ -0,0 +1,6 @@ +- name: Install virtualenv + package: + name: + - python-virtualenv + become: yes + diff --git a/roles/ensure-virtualenv/tasks/Debian.yaml b/roles/ensure-virtualenv/tasks/Debian.yaml new file mode 100644 index 000000000..b2d498b0b --- /dev/null +++ b/roles/ensure-virtualenv/tasks/Debian.yaml @@ -0,0 +1,5 @@ +- name: Install virtualenv + package: + name: + - virtualenv + become: yes diff --git a/roles/ensure-virtualenv/tasks/Gentoo.yaml b/roles/ensure-virtualenv/tasks/Gentoo.yaml new file mode 100644 index 000000000..8ff8c8945 --- /dev/null +++ b/roles/ensure-virtualenv/tasks/Gentoo.yaml @@ -0,0 +1,5 @@ +- name: Install virtualenv + package: + name: dev-python/virtualenv + become: yes + diff --git a/roles/ensure-virtualenv/tasks/RedHat.yaml b/roles/ensure-virtualenv/tasks/RedHat.yaml new file mode 100644 index 000000000..98f7a071b --- /dev/null +++ b/roles/ensure-virtualenv/tasks/RedHat.yaml @@ -0,0 +1,6 @@ +- name: Install virtualenv + package: + name: + - python3-virtualenv + become: yes + diff --git a/roles/ensure-virtualenv/tasks/Suse.yaml b/roles/ensure-virtualenv/tasks/Suse.yaml new file mode 100644 index 000000000..8e129ce2b --- /dev/null +++ b/roles/ensure-virtualenv/tasks/Suse.yaml @@ -0,0 +1,4 @@ +- name: Install virtualenv + package: + name: python3-virtualenv + become: yes diff --git a/roles/ensure-virtualenv/tasks/default.yaml b/roles/ensure-virtualenv/tasks/default.yaml new file mode 100644 index 000000000..fd6bb8fbb --- /dev/null +++ b/roles/ensure-virtualenv/tasks/default.yaml @@ -0,0 +1,3 @@ +- name: Unsupported platform + fail: + msg: 'This platform is currently unsupported' diff --git a/roles/ensure-virtualenv/tasks/main.yaml b/roles/ensure-virtualenv/tasks/main.yaml new file mode 100644 index 000000000..ede55216f --- /dev/null +++ b/roles/ensure-virtualenv/tasks/main.yaml @@ -0,0 +1,18 @@ +- name: Check if virtualenv is installed + shell: | + command -v virtualenv || exit 1 + args: + executable: /bin/bash + register: virtualenv_preinstalled + failed_when: false + +- name: Install virtualenv package + include: "{{ item }}" + with_first_found: + - "{{ ansible_distribution }}-{{ ansible_distribution_major_version }}.yaml" + - "{{ ansible_distribution_release }}.yaml" + - "{{ ansible_distribution }}.yaml" + - "{{ ansible_os_family }}.yaml" + - "default.yaml" + when: + - virtualenv_preinstalled.rc != 0 diff --git a/test-playbooks/ensure-pip.yaml b/test-playbooks/ensure-pip.yaml index 8fb39a02c..498dbe4ab 100644 --- a/test-playbooks/ensure-pip.yaml +++ b/test-playbooks/ensure-pip.yaml @@ -1,7 +1,9 @@ - hosts: all - roles: - - ensure-pip tasks: + - name: Include ensure-pip + include_role: + name: ensure-pip + - name: Sanity check provided virtualenv command works shell: | tmp_venv=$(mktemp -d -t venv-XXXXXXXXXX) @@ -11,12 +13,31 @@ failed_when: false register: _venv_sanity - - name: Assert sanity check + - name: Assert pip venv sanity check fail: msg: 'The virtualenv_command: "{{ ensure_pip_virtualenv_command }}" does not appear to work!' when: - _venv_sanity.rc != 0 + - name: Include ensure-virtualenv + include_role: + name: ensure-virtualenv + + - name: Sanity check virtualenv command works + shell: | + tmp_venv=$(mktemp -d -t venv-XXXXXXXXXX) + trap "rm -rf $tmp_venv" EXIT + virtualenv $tmp_venv + $tmp_venv/bin/pip install tox + failed_when: false + register: _virtualenv_sanity + + - name: Assert sanity check + fail: + msg: 'The virtualenv command does not appear to work!' + when: + - _virtualenv_sanity.rc != 0 + # NOTE(ianw) : this does not play nicely with pip-and-virtualenv which # has already installed from source. We might be able to test this # once it's gone... diff --git a/zuul-tests.d/python-jobs.yaml b/zuul-tests.d/python-jobs.yaml index eb213c82e..79eb4d6eb 100644 --- a/zuul-tests.d/python-jobs.yaml +++ b/zuul-tests.d/python-jobs.yaml @@ -3,6 +3,7 @@ description: Test the ensure-pip role files: - roles/ensure-pip/.* + - roles/ensure-virtualenv/.* run: test-playbooks/ensure-pip.yaml tags: all-platforms