Merge "Revise the role to properly cater to use-cases"
This commit is contained in:
commit
49c41457db
19
README.rst
19
README.rst
|
@ -13,6 +13,25 @@ OpenStack-Ansible python_venv_build
|
|||
|
||||
This Ansible role prepares a python venv for use in OpenStack-Ansible.
|
||||
|
||||
The role requires the following to be present prior to execution:
|
||||
|
||||
* pip >= 7.1 (to support using the constraints option)
|
||||
* virtualenv >= 13.0.0 (to support using the no-pip, no-setuptools, no-wheels
|
||||
options)
|
||||
|
||||
Use-cases
|
||||
~~~~~~~~~
|
||||
|
||||
This role is built to cater to the following use-cases:
|
||||
|
||||
# Execute a build against a build host, then serve the venvs from a web
|
||||
server.
|
||||
# Execute a build against the first host in a group, then serving the
|
||||
venvs from the deployment host.
|
||||
|
||||
References
|
||||
~~~~~~~~~~
|
||||
|
||||
Documentation for the project can be found at:
|
||||
https://docs.openstack.org/openstack-ansible-python_venv_build/latest/
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
# The path where venvs are extracted to
|
||||
# on the target host during an install, for example:
|
||||
# venv_destination_path: "/openstack/venvs/myvenv"
|
||||
# venv_install_destination_path: "/openstack/venvs/myvenv"
|
||||
|
||||
#
|
||||
# Optional variables
|
||||
|
@ -27,70 +27,59 @@
|
|||
|
||||
# Distribution packages which must be installed
|
||||
# on the host for the purpose of building the venv.
|
||||
distro_package_list: []
|
||||
venv_build_distro_package_list: []
|
||||
|
||||
# Distribution packages which must be installed
|
||||
# on the host when installing the venv.
|
||||
venv_install_distro_package_list: []
|
||||
|
||||
# Set the package install state for packages
|
||||
# Options are 'present' and 'latest'
|
||||
distro_package_state: "latest"
|
||||
pip_package_state: "latest"
|
||||
venv_distro_package_state: "latest"
|
||||
venv_pip_package_state: "latest"
|
||||
|
||||
# The time in seconds that the distribution package
|
||||
# cache is valid for. This is only used by the apt
|
||||
# and zypper package managers.
|
||||
distro_cache_valid_time: 600
|
||||
|
||||
# Python packages which must be installed
|
||||
# on to the host for the purpose of building
|
||||
# the venv.
|
||||
host_pip_packages: []
|
||||
|
||||
# Arguments to pass to the installation
|
||||
# of pip packages on the host.
|
||||
host_pip_install_args: ""
|
||||
venv_distro_cache_valid_time: 600
|
||||
|
||||
# Python packages which must be installed
|
||||
# into the venv.
|
||||
venv_pip_packages: []
|
||||
|
||||
# Arguments to pass to the venv build
|
||||
# Arguments to pass to pip when installing into the venv
|
||||
venv_pip_install_args: ""
|
||||
|
||||
# Enable the reuse of venvs across multiple hosts.
|
||||
# This sets the build process to copy the venv to
|
||||
# the deployment host once it's built, then to
|
||||
# re-use the venv in subsequent deployments.
|
||||
venv_reuse_enable: yes
|
||||
# The python executable to use for creating the venv
|
||||
venv_python_executable: "python2"
|
||||
|
||||
# Enable the ability to *only* do the build, so that
|
||||
# the deploy host can be pre-populated with the venvs.
|
||||
venv_reuse_build_only: no
|
||||
# the build host can be pre-populated with the venvs.
|
||||
venv_build_only: no
|
||||
|
||||
# Enable the packaging of venvs, so that they can
|
||||
# be used for installation.
|
||||
venv_build_package: yes
|
||||
|
||||
# Enable the use of wheels to speed up the venv
|
||||
# build process, especially when building multiple
|
||||
# venvs.
|
||||
venv_reuse_build_wheels: yes
|
||||
venv_build_wheels: yes
|
||||
|
||||
# The path where a built venv is stored on the By default,
|
||||
# a path on the deployment host is used which ensures that
|
||||
# the location separates venvs per distribution and architecture
|
||||
# to prevent re-use of venvs between them. If the path set
|
||||
# begins with http(s):// then the install process will
|
||||
# recognise this and deploy from a URL instead of the
|
||||
# deployment host.
|
||||
venv_reuse_download_venv_path: "{{ lookup('env', 'HOME') | default('/opt', true) }}/cache/venvs/{{ venv_reuse_download_subfolder }}"
|
||||
|
||||
# NOTE(hwoarang): ansible_distribution may return a string with spaces
|
||||
# such as "openSUSE Leap" so we need to replace the space with underscore
|
||||
# in order to create a more sensible repo name for the distro.
|
||||
venv_reuse_download_subfolder: "{{ (ansible_distribution | lower) | replace(' ', '_') }}-{{ ansible_distribution_version.split('.')[:2] | join('.') }}-{{ ansible_architecture | lower }}"
|
||||
|
||||
# The owner of the venv_reuse_download_venv_path if it is
|
||||
# housed on the deployment host.
|
||||
venv_reuse_download_path_owner: "{{ lookup('env', 'USER') | default('root', true) }}"
|
||||
|
||||
# The path where the wheels are cached on the target host
|
||||
# The path where the wheels are cached on the build host
|
||||
# for speeding up the build process.
|
||||
venv_wheel_destination_path: "/var/cache/python_wheels"
|
||||
venv_build_wheel_path: "{{ lookup('env', 'HOME') }}/archive/wheels"
|
||||
|
||||
# The path where the venvs are archived on the build host
|
||||
# to be reused for installations.
|
||||
venv_build_archive_path: "{{ lookup('env', 'HOME') }}/archive/venvs"
|
||||
|
||||
# The path where a built venv is sourced from when
|
||||
# installing. If the path set begins with https(s)://
|
||||
# then the install process will recognise the source
|
||||
# is a web server. Otherwise the path is assumed to
|
||||
# be on the deployment host.
|
||||
venv_install_source_path: "{{ lookup('env', 'HOME') }}/archive/venvs"
|
||||
|
||||
# The facts to set when the venv changes during a
|
||||
# build, or the installation of a venv.
|
||||
|
|
|
@ -13,6 +13,6 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
- meta: noop
|
||||
listen: venv changed
|
||||
- name: venv changed
|
||||
meta: noop
|
||||
when: false
|
||||
|
|
|
@ -20,27 +20,28 @@
|
|||
# To ensure that only the first host in every distro/architecture
|
||||
# group does the build, and the others make use of that build,
|
||||
# without forcing the use of serialisation, we use a dynamic
|
||||
# group based on the venv_reuse_download_subfolder which combines
|
||||
# group based on the venv_distro_arch_grouping which combines
|
||||
# the distribution/architecture and is therefore unique for mixed
|
||||
# environments.
|
||||
- name: Add hosts to dynamic inventory group to ensure build/install serialization
|
||||
group_by:
|
||||
key: "{{ venv_reuse_download_subfolder }}"
|
||||
key: "{{ venv_distro_arch_grouping }}"
|
||||
tags:
|
||||
- always
|
||||
|
||||
- include_tasks: "python_venv_build.yml"
|
||||
when:
|
||||
- (not _src_venv_present.stat.exists | bool) or
|
||||
(not venv_reuse_enable | bool)
|
||||
- inventory_hostname == groups[venv_reuse_download_subfolder][0]
|
||||
- (venv_build_only | bool) or
|
||||
((_venv_source == 'file') and
|
||||
(not _src_venv_present.stat.exists | bool))
|
||||
- inventory_hostname == groups[venv_distro_arch_grouping][0]
|
||||
|
||||
- include_tasks: "python_venv_install.yml"
|
||||
when:
|
||||
- venv_reuse_enable | bool
|
||||
- not venv_reuse_build_only | bool
|
||||
- (_src_venv_present.stat.exists | bool) or
|
||||
inventory_hostname != groups[venv_reuse_download_subfolder][0]
|
||||
- not venv_build_only | bool
|
||||
- inventory_hostname != groups[venv_distro_arch_grouping][0]
|
||||
|
||||
- include_tasks: "python_venv_set_facts.yml"
|
||||
when:
|
||||
- not venv_reuse_build_only | bool
|
||||
- not venv_build_only | bool
|
||||
- venv_facts_when_changed != []
|
||||
|
|
|
@ -15,44 +15,44 @@
|
|||
|
||||
- name: Install distro packages for venv build
|
||||
package:
|
||||
name: "{{ distro_package_list }}"
|
||||
state: "{{ distro_package_state }}"
|
||||
name: "{{ venv_build_distro_package_list + venv_install_distro_package_list }}"
|
||||
state: "{{ venv_distro_package_state }}"
|
||||
update_cache: "{{ (ansible_pkg_mgr in ['apt', 'zypper']) | ternary('yes', omit) }}"
|
||||
cache_valid_time: "{{ (ansible_pkg_mgr == 'apt') | ternary(distro_cache_valid_time, omit) }}"
|
||||
when: distro_package_list | length > 0
|
||||
when:
|
||||
- (venv_build_distro_package_list | length > 0) or
|
||||
(venv_install_distro_package_list | length > 0)
|
||||
register: _install_distro_packages
|
||||
until: _install_distro_packages | success
|
||||
retries: 5
|
||||
delay: 2
|
||||
|
||||
- name: Install pip packages on the host for venv build
|
||||
pip:
|
||||
name: "{{ host_pip_packages }}"
|
||||
state: "{{ pip_package_state }}"
|
||||
extra_args: "{{ host_pip_install_args }}"
|
||||
when: host_pip_packages | length > 0
|
||||
register: _install_host_pip_packages
|
||||
until: _install_host_pip_packages | success
|
||||
retries: 5
|
||||
delay: 2
|
||||
- name: Ensure a fresh venv_install_destination_path if venv_build_only is enabled
|
||||
file:
|
||||
path: "{{ venv_install_destination_path }}"
|
||||
state: absent
|
||||
when:
|
||||
- venv_build_only | bool
|
||||
|
||||
- name: Create wheel/venv directories on the target host
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
with_items:
|
||||
- "{{ venv_destination_path }}"
|
||||
- "{{ venv_wheel_destination_path }}"
|
||||
- "{{ venv_build_archive_path }}"
|
||||
- "{{ venv_build_wheel_path }}"
|
||||
- "{{ venv_install_destination_path }}"
|
||||
|
||||
- name: Build wheels for the packages to be installed into the venv
|
||||
command: >-
|
||||
pip wheel
|
||||
--wheel-dir {{ venv_wheel_destination_path }}/
|
||||
--find-links {{ venv_wheel_destination_path }}/
|
||||
--wheel-dir {{ venv_build_wheel_path }}/
|
||||
--find-links {{ venv_build_wheel_path }}/
|
||||
--log /var/log/python_wheel_build.log
|
||||
{{ venv_pip_install_args }}
|
||||
{{ venv_pip_packages | join(' ') }}
|
||||
when: venv_reuse_build_wheels | bool
|
||||
when:
|
||||
- venv_build_wheels | bool
|
||||
|
||||
#TODO(odyssey4me):
|
||||
# Split the venv build into multiple parts:
|
||||
|
@ -64,11 +64,12 @@
|
|||
- name: Build venv
|
||||
pip:
|
||||
name: "{{ venv_pip_packages }}"
|
||||
state: "{{ pip_package_state }}"
|
||||
virtualenv: "{{ venv_destination_path }}"
|
||||
state: "{{ venv_pip_package_state }}"
|
||||
virtualenv: "{{ venv_install_destination_path }}"
|
||||
virtualenv_site_packages: "no"
|
||||
virtualenv_python: "{{ venv_python_executable }}"
|
||||
extra_args: >-
|
||||
--find-links {{ venv_wheel_destination_path }}/
|
||||
--find-links {{ venv_build_wheel_path }}/
|
||||
--log /var/log/python_venv_build.log
|
||||
{{ venv_pip_install_args }}
|
||||
register: _install_venv_pip_packages
|
||||
|
@ -78,53 +79,66 @@
|
|||
notify:
|
||||
- venv changed
|
||||
|
||||
- name: Package the venv when venv_reuse_enable is enabled
|
||||
- name: Package the venv when venv_build_package is enabled
|
||||
when:
|
||||
- venv_reuse_enable | bool
|
||||
- venv_build_package | bool
|
||||
block:
|
||||
|
||||
- name: Clean up the virtualenv before packaging
|
||||
shell: |
|
||||
find {{ venv_destination_path }}/bin -type f -name '*.pyc' -delete
|
||||
when:
|
||||
- _install_venv_pip_packages is mapping
|
||||
- _install_venv_pip_packages | changed
|
||||
- name: Clean up the virtualenv before packaging
|
||||
shell: |
|
||||
find {{ venv_install_destination_path }}/bin -type f -name '*.pyc' -delete
|
||||
when:
|
||||
- _install_venv_pip_packages is mapping
|
||||
- _install_venv_pip_packages | changed
|
||||
|
||||
# Note(odyssey4me):
|
||||
# We purposefully use shell instead of the archive module
|
||||
# here. The archive module's output is far too verbose to
|
||||
# be practical when debugging.
|
||||
- name: Package venv
|
||||
command: |
|
||||
tar czf '{{ venv_destination_path }}.tgz' -C '{{ venv_destination_path }}' .
|
||||
args:
|
||||
chdir: "{{ venv_destination_path }}"
|
||||
warn: no
|
||||
register: _venv_package_build
|
||||
when:
|
||||
- _install_venv_pip_packages is mapping
|
||||
- _install_venv_pip_packages | changed
|
||||
# Note(odyssey4me):
|
||||
# We purposefully use shell instead of the archive module
|
||||
# here. The archive module's output is far too verbose to
|
||||
# be practical when debugging.
|
||||
- name: Package venv
|
||||
command: |
|
||||
tar czf '{{ venv_build_archive_path }}/{{ venv_install_destination_path | basename }}.tgz' -C '{{ venv_install_destination_path }}' .
|
||||
args:
|
||||
chdir: "{{ venv_install_destination_path }}"
|
||||
warn: no
|
||||
register: _venv_package_build
|
||||
when:
|
||||
- _install_venv_pip_packages is mapping
|
||||
- _install_venv_pip_packages | changed
|
||||
|
||||
- name: Prepare checksum for packaged venv
|
||||
shell: |
|
||||
sha1sum '{{ venv_destination_path }}.tgz' | awk '{print $1}' > '{{ venv_destination_path }}.checksum'
|
||||
args:
|
||||
executable: /bin/bash
|
||||
when:
|
||||
- _venv_package_build is mapping
|
||||
- _venv_package_build | changed
|
||||
- name: Prepare checksum for packaged venv
|
||||
shell: |
|
||||
sha1sum '{{ venv_build_archive_path }}/{{ venv_install_destination_path | basename }}.tgz' | awk '{print $1}' > '{{ venv_build_archive_path }}/{{ venv_install_destination_path | basename }}.checksum'
|
||||
args:
|
||||
executable: /bin/bash
|
||||
when:
|
||||
- _venv_package_build is mapping
|
||||
- _venv_package_build | changed
|
||||
|
||||
- name: Copy the packaged venv and checksum file to the deployment host
|
||||
fetch:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
flat: yes
|
||||
with_items:
|
||||
- src: "{{ venv_destination_path }}.tgz"
|
||||
dest: "{{ venv_reuse_download_venv_path }}/{{ venv_destination_path | basename }}.tgz"
|
||||
- src: "{{ venv_destination_path }}.checksum"
|
||||
dest: "{{ venv_reuse_download_venv_path }}/{{ venv_destination_path | basename }}.checksum"
|
||||
when:
|
||||
- _venv_source == 'file'
|
||||
- _venv_package_build is mapping
|
||||
- _venv_package_build | changed
|
||||
- name: Ensure that venv_install_source_path exists on the deployment host
|
||||
file:
|
||||
path: "{{ venv_install_source_path }}"
|
||||
state: directory
|
||||
owner: "{{ lookup('env', 'USER') }}"
|
||||
recurse: yes
|
||||
delegate_to: localhost
|
||||
run_once: yes
|
||||
when:
|
||||
- _venv_source == 'file'
|
||||
- inventory_hostname != 'localhost'
|
||||
|
||||
- name: Copy the packaged venv and checksum file to the deployment host
|
||||
fetch:
|
||||
src: "{{ item.src }}"
|
||||
dest: "{{ item.dest }}"
|
||||
flat: yes
|
||||
with_items:
|
||||
- src: "{{ venv_build_archive_path }}/{{ venv_install_destination_path | basename }}.tgz"
|
||||
dest: "{{ venv_install_source_path }}/{{ venv_install_destination_path | basename }}.tgz"
|
||||
- src: "{{ venv_build_archive_path }}/{{ venv_install_destination_path | basename }}.checksum"
|
||||
dest: "{{ venv_install_source_path }}/{{ venv_install_destination_path | basename }}.checksum"
|
||||
when:
|
||||
- _venv_source == 'file'
|
||||
- _venv_package_build is mapping
|
||||
- _venv_package_build | changed
|
||||
- inventory_hostname != 'localhost'
|
||||
|
|
|
@ -13,34 +13,59 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
- name: Copy the venv checksum file to the target host
|
||||
- name: Install distro packages for venv install
|
||||
package:
|
||||
name: "{{ venv_install_distro_package_list }}"
|
||||
state: "{{ venv_distro_package_state }}"
|
||||
update_cache: "{{ (ansible_pkg_mgr in ['apt', 'zypper']) | ternary('yes', omit) }}"
|
||||
cache_valid_time: "{{ (ansible_pkg_mgr == 'apt') | ternary(distro_cache_valid_time, omit) }}"
|
||||
when:
|
||||
- venv_install_distro_package_list | length > 0
|
||||
register: _install_distro_packages
|
||||
until: _install_distro_packages | success
|
||||
retries: 5
|
||||
delay: 2
|
||||
|
||||
- name: Create venv parent directories on the target host
|
||||
file:
|
||||
path: "{{ venv_install_destination_path | dirname }}"
|
||||
state: directory
|
||||
|
||||
- name: Copy the venv archive checksum
|
||||
copy:
|
||||
src: "{{ venv_reuse_download_venv_path }}/{{ venv_destination_path | basename }}.checksum"
|
||||
dest: "{{ venv_destination_path | dirname }}/"
|
||||
src: "{{ venv_install_source_path }}/{{ venv_install_destination_path | basename }}.checksum"
|
||||
dest: "{{ venv_install_destination_path | dirname }}/"
|
||||
register: _venv_checksum_copy
|
||||
when:
|
||||
- _venv_source == 'file'
|
||||
|
||||
- name: Retrieve checksum for venv download
|
||||
- name: Copy the venv archive
|
||||
copy:
|
||||
src: "{{ venv_install_source_path }}/{{ venv_install_destination_path | basename }}.tgz"
|
||||
dest: "{{ venv_install_destination_path | dirname }}/"
|
||||
when:
|
||||
- _venv_source == 'file'
|
||||
|
||||
- name: Download the venv archive checksum
|
||||
uri:
|
||||
url: "{{ venv_reuse_download_venv_path }}/{{ venv_destination_path | basename }}.checksum"
|
||||
dest: "{{ venv_destination_path | dirname }}/"
|
||||
url: "{{ venv_install_source_path }}/{{ venv_install_destination_path | basename }}.checksum"
|
||||
dest: "{{ venv_install_destination_path | dirname }}/"
|
||||
return_content: yes
|
||||
register: _venv_checksum_download
|
||||
when:
|
||||
- _venv_source == 'url'
|
||||
|
||||
- name: Attempt venv download
|
||||
- name: Download the venv archive
|
||||
get_url:
|
||||
url: "{{ venv_reuse_download_venv_path }}/{{ venv_destination_path | basename }}.tgz"
|
||||
dest: "{{ venv_destination_path | dirname }}/"
|
||||
url: "{{ venv_install_source_path }}/{{ venv_install_destination_path | basename }}.tgz"
|
||||
dest: "{{ venv_install_destination_path | dirname }}/"
|
||||
checksum: "sha1:{{ _venv_checksum_download.content | trim }}"
|
||||
when:
|
||||
- _venv_source == 'url'
|
||||
|
||||
- name: Remove existing venv on target host if it is changing
|
||||
file:
|
||||
path: "{{ venv_destination_path }}"
|
||||
path: "{{ venv_install_destination_path }}"
|
||||
state: absent
|
||||
when:
|
||||
- (_venv_checksum_copy is mapping and _venv_checksum_copy | changed) or
|
||||
|
@ -48,15 +73,15 @@
|
|||
|
||||
- name: Create venv directory on the target host
|
||||
file:
|
||||
path: "{{ venv_destination_path }}"
|
||||
path: "{{ venv_install_destination_path }}"
|
||||
state: directory
|
||||
register: _venv_dir_create
|
||||
|
||||
- name: Unarchive pre-built venv
|
||||
unarchive:
|
||||
src: "{{ venv_reuse_download_venv_path }}/{{ venv_destination_path | basename }}.tgz"
|
||||
dest: "{{ venv_destination_path }}"
|
||||
remote_src: no
|
||||
src: "{{ venv_install_destination_path }}.tgz"
|
||||
dest: "{{ venv_install_destination_path }}"
|
||||
remote_src: yes
|
||||
when:
|
||||
- (_venv_checksum_copy is mapping and _venv_checksum_copy | changed) or
|
||||
(_venv_checksum_download is mapping and _venv_checksum_download | changed) or
|
||||
|
@ -73,8 +98,8 @@
|
|||
# to https://github.com/pypa/virtualenv/issues/565
|
||||
- name: Update virtualenv python and paths
|
||||
shell: |
|
||||
sed -si '1s/^.*python.*$/#!{{ (venv_destination_path ~ '/bin') | replace ('/','\/') }}\/python/' {{ venv_destination_path }}/bin/*
|
||||
virtualenv {{ venv_destination_path }} \
|
||||
sed -si '1s/^.*python.*$/#!{{ (venv_install_destination_path ~ '/bin') | replace ('/','\/') }}\/python/' {{ venv_install_destination_path }}/bin/*
|
||||
virtualenv {{ venv_install_destination_path }} \
|
||||
{{ (ansible_pkg_mgr == 'apt') | ternary('--always-copy', '') }} \
|
||||
--no-pip \
|
||||
--no-setuptools \
|
||||
|
|
|
@ -13,43 +13,59 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
- name: Verify that venv_destination_path has been provided
|
||||
- name: Verify that venv_install_destination_path has been provided
|
||||
fail:
|
||||
msg: |
|
||||
The variable venv_destination_path is required and
|
||||
has not been set
|
||||
The variable venv_install_destination_path is required and
|
||||
has not been set.
|
||||
when:
|
||||
- venv_destination_path is not defined
|
||||
- venv_install_destination_path is not defined
|
||||
|
||||
- name: Verify that venv_reuse_enable and venv_reuse_build_only are not interfering with each other
|
||||
- name: Collect the version of virtualenv
|
||||
shell: |
|
||||
virtualenv --version 2>/dev/null || echo 'none'
|
||||
args:
|
||||
executable: /bin/bash
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
register: _virtualenv_version
|
||||
|
||||
- name: Collect the version of pip
|
||||
shell: |
|
||||
pip --version 2>/dev/null | awk '{print $2}' || echo 'none'
|
||||
args:
|
||||
executable: /bin/bash
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
register: _pip_version
|
||||
|
||||
- name: Fail when required virtualenv version is not present
|
||||
fail:
|
||||
msg: |
|
||||
If venv_reuse_build_only is enabled, then venv_reuse_enable must also
|
||||
be enabled.
|
||||
The variable venv_reuse_enable is set to {{ venv_reuse_enable }}.
|
||||
The variable venv_reuse_build_only is set to {{ venv_reuse_build_only }}.
|
||||
msg: >-
|
||||
The required virtualenv version is not present.
|
||||
The minimum version of 13.0.0 is required, but
|
||||
{{ _virtualenv_version.stdout }} is installed.
|
||||
when:
|
||||
- venv_reuse_build_only | bool
|
||||
- not venv_reuse_enable | bool
|
||||
- ((_virtualenv_version.stdout | trim) == 'none') or
|
||||
((_virtualenv_version.stdout | trim) is version_compare('13.0.0', '<'))
|
||||
|
||||
- name: Check whether the venv_reuse_download_venv_path is a URL or a file path
|
||||
- name: Fail when required pip version is not present
|
||||
fail:
|
||||
msg: >-
|
||||
The required virtualenv version is not present.
|
||||
The minimum version of 7.1 is required, but
|
||||
{{ _pip_version.stdout }} is installed.
|
||||
when:
|
||||
- ((_pip_version.stdout | trim) == 'none') or
|
||||
((_pip_version.stdout | trim) is version_compare('7.1', '<'))
|
||||
|
||||
- name: Check whether the venv_install_source_path is a URL or a file path
|
||||
set_fact:
|
||||
_venv_source: "{{ (venv_reuse_download_venv_path is match('^https?://.*')) | ternary('url', 'file') }}"
|
||||
|
||||
- name: Ensure that venv_reuse_download_path exists on the deployment host
|
||||
file:
|
||||
path: "{{ venv_reuse_download_venv_path }}"
|
||||
state: directory
|
||||
owner: "{{ venv_reuse_download_path_owner }}"
|
||||
delegate_to: localhost
|
||||
run_once: yes
|
||||
when:
|
||||
- _venv_source == 'file'
|
||||
- venv_reuse_enable | bool
|
||||
_venv_source: "{{ ((venv_install_source_path | trim) is match('^https?://.*')) | ternary('url', 'file') }}"
|
||||
|
||||
- name: Check if venv tgz is present on the deployment host
|
||||
stat:
|
||||
path: "{{ venv_reuse_download_venv_path }}/{{ venv_destination_path | basename }}.tgz"
|
||||
path: "{{ venv_install_source_path }}/{{ venv_install_destination_path | basename }}.tgz"
|
||||
get_attributes: no
|
||||
get_checksum: no
|
||||
get_md5: no
|
||||
|
@ -59,14 +75,3 @@
|
|||
run_once: yes
|
||||
when:
|
||||
- _venv_source == 'file'
|
||||
- venv_reuse_enable | bool
|
||||
|
||||
- name: Ensure that virtualenv is installed on the destination host
|
||||
pip:
|
||||
name: virtualenv
|
||||
state: "{{ pip_package_state }}"
|
||||
extra_args: "{{ host_pip_install_args }}"
|
||||
register: _install_host_pip_virtualenv
|
||||
until: _install_host_pip_virtualenv | success
|
||||
retries: 5
|
||||
delay: 2
|
||||
|
|
|
@ -3,18 +3,8 @@ localhost
|
|||
container1
|
||||
container2
|
||||
container3
|
||||
container4
|
||||
|
||||
[all_containers]
|
||||
container1
|
||||
container2
|
||||
container3
|
||||
container4
|
||||
|
||||
[test1]
|
||||
container1
|
||||
container2
|
||||
|
||||
[test2]
|
||||
container3
|
||||
container4
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
# limitations under the License.
|
||||
|
||||
- name: Clean up from previous tests
|
||||
hosts: "{{ target_host_group_name }}:localhost"
|
||||
hosts: "{{ build_host }}:{{ install_hosts }}"
|
||||
become: yes
|
||||
any_errors_fatal: yes
|
||||
tasks:
|
||||
|
@ -22,42 +22,87 @@
|
|||
file:
|
||||
path: "{{ item.path }}"
|
||||
state: absent
|
||||
when: item.condition | default(omit)
|
||||
with_items:
|
||||
- path: "{{ lookup('env', 'HOME') | default('/opt', true) }}/venvs"
|
||||
- path: "{{ lookup('env', 'HOME') | default('/opt', true) }}/cache/venvs"
|
||||
- path: "{{ lookup('env', 'HOME') | default('/opt', true) }}/cache/wheels"
|
||||
condition: "{{ target_host_group_name == 'test1' }}"
|
||||
- path: "/var/cache/python_wheels"
|
||||
- path: "{{ lookup('env', 'HOME') }}/archive"
|
||||
- path: "{{ lookup('env', 'HOME') }}/venvs"
|
||||
|
||||
- name: Clean up facts from previous tests
|
||||
ini_file:
|
||||
path: "/etc/ansible/facts.d/openstack_ansible.fact"
|
||||
section: "{{ target_host_group_name }}"
|
||||
section: "{{ item }}"
|
||||
state: absent
|
||||
with_items: "{{ build_host.split(':') + install_hosts.split(':') }}"
|
||||
|
||||
- name: Refresh the inventory to clear the added groups
|
||||
meta: refresh_inventory
|
||||
|
||||
- name: Execute role test and verify target host content
|
||||
hosts: "{{ target_host_group_name }}"
|
||||
- name: Set venv_build_archive_path and venv_install_source_path
|
||||
set_fact:
|
||||
venv_build_archive_path: >-
|
||||
{%- if build_host == "container1" %}
|
||||
{%- if ansible_distribution == "Ubuntu" %}
|
||||
{%- set _path = "/var/www/html" %}
|
||||
{%- elif ansible_distribution == "CentOS" %}
|
||||
{%- set _path = "/usr/share/nginx/html" %}
|
||||
{%- else %}
|
||||
{%- set _path = "/srv/www/htdocs" %}
|
||||
{%- endif %}
|
||||
{%- else -%}
|
||||
{%- set _path = lookup('env', 'HOME') ~ "/archive/venvs" -%}
|
||||
{%- endif -%}
|
||||
{{- _path }}
|
||||
venv_install_source_path: >-
|
||||
{%- if build_host == "container1" -%}
|
||||
http://{{ hostvars['container1'].ansible_default_ipv4.address }}
|
||||
{%- else -%}
|
||||
{{- lookup('env', 'HOME') }}/archive/venvs
|
||||
{%- endif -%}
|
||||
|
||||
- name: Install distro packages
|
||||
package:
|
||||
name: "nginx"
|
||||
update_cache: "{{ (ansible_pkg_mgr in ['apt', 'zypper']) | ternary('yes', omit) }}"
|
||||
register: install
|
||||
until: install | success
|
||||
retries: 5
|
||||
delay: 2
|
||||
when:
|
||||
- inventory_hostname == 'container1'
|
||||
|
||||
- name: Enable and start nginx
|
||||
service:
|
||||
name: nginx
|
||||
enabled: yes
|
||||
daemon_reload: yes
|
||||
state: restarted
|
||||
when:
|
||||
- inventory_hostname == 'container1'
|
||||
|
||||
- name: Execute build
|
||||
hosts: "{{ build_host }}"
|
||||
become: yes
|
||||
any_errors_fatal: yes
|
||||
serial: "{{ target_serial }}"
|
||||
vars:
|
||||
base_directory: "{{ lookup('env', 'HOME') | default('/opt', true) }}"
|
||||
tasks:
|
||||
|
||||
- name: Execute role
|
||||
- name: Execute venv build
|
||||
include_role:
|
||||
name: "python_venv_build"
|
||||
private: yes
|
||||
vars:
|
||||
venv_build_only: yes
|
||||
|
||||
- name: Execute install
|
||||
hosts: "{{ install_hosts }}"
|
||||
become: yes
|
||||
any_errors_fatal: yes
|
||||
tasks:
|
||||
|
||||
- name: Execute venv install
|
||||
include_role:
|
||||
name: "python_venv_build"
|
||||
private: yes
|
||||
vars:
|
||||
venv_pip_packages:
|
||||
- "Jinja2==2.10"
|
||||
venv_destination_path: "{{ base_directory }}/venvs/{{ target_host_group_name }}"
|
||||
venv_facts_when_changed:
|
||||
- section: "{{ target_host_group_name }}"
|
||||
- section: "{{ inventory_hostname }}"
|
||||
option: "test"
|
||||
value: True
|
||||
|
||||
|
@ -73,7 +118,7 @@
|
|||
- name: Verify that the facts were set
|
||||
assert:
|
||||
that:
|
||||
- ansible_local['openstack_ansible'][target_host_group_name]['test'] | bool
|
||||
- ansible_local['openstack_ansible'][inventory_hostname]['test'] | bool
|
||||
|
||||
- name: Find files/folders on targets
|
||||
find:
|
||||
|
@ -81,17 +126,12 @@
|
|||
get_checksum: no
|
||||
recurse: no
|
||||
paths:
|
||||
- "{{ base_directory }}/venvs"
|
||||
- "{{ venv_install_destination_path | dirname }}"
|
||||
register: _target_folders
|
||||
|
||||
- name: Compile the folder list from the targets
|
||||
set_fact:
|
||||
_target_folder_list: >-
|
||||
{%- set folder_list = [] %}
|
||||
{%- for item in _target_folders['files'] %}
|
||||
{%- set _ = folder_list.append(item['path']) %}
|
||||
{%- endfor %}
|
||||
{{ folder_list }}
|
||||
_target_folder_list: "{{ _target_folders['files'] | map(attribute='path') | list }}"
|
||||
|
||||
- name: Show the files/folder from the targets
|
||||
debug:
|
||||
|
@ -100,43 +140,4 @@
|
|||
- name: Verify the folder list from the targets
|
||||
assert:
|
||||
that:
|
||||
- "{{ base_directory ~ '/venvs/' ~ target_host_group_name in _target_folder_list }}"
|
||||
|
||||
- name: Verify deploy host content
|
||||
hosts: localhost
|
||||
connection: local
|
||||
become: yes
|
||||
any_errors_fatal: yes
|
||||
vars:
|
||||
base_directory: "{{ lookup('env', 'HOME') | default('/opt', true) }}"
|
||||
sub_directory: "{{ (ansible_distribution | lower) | replace(' ', '_') }}-{{ ansible_distribution_version.split('.')[:2] | join('.') }}-{{ ansible_architecture | lower }}"
|
||||
package_file_path: "{{ base_directory }}/cache/venvs/{{ sub_directory }}/{{ target_host_group_name }}"
|
||||
tasks:
|
||||
|
||||
- name: Find files/folders on deploy host
|
||||
find:
|
||||
file_type: any
|
||||
get_checksum: no
|
||||
recurse: yes
|
||||
paths:
|
||||
- "{{ base_directory }}/cache"
|
||||
register: _localhost_folders
|
||||
|
||||
- name: Compile the folder list from the deploy host
|
||||
set_fact:
|
||||
_localhost_folder_list: >-
|
||||
{%- set folder_list = [] %}
|
||||
{%- for item in _localhost_folders['files'] %}
|
||||
{%- set _ = folder_list.append(item['path']) %}
|
||||
{%- endfor %}
|
||||
{{ folder_list }}
|
||||
|
||||
- name: Show the files/folders from the deploy host
|
||||
debug:
|
||||
var: _localhost_folder_list
|
||||
|
||||
- name: Verify the folder list from the deploy host
|
||||
assert:
|
||||
that:
|
||||
- "{{ package_file_path ~ '.tgz' in _localhost_folder_list }}"
|
||||
- "{{ package_file_path ~ '.checksum' in _localhost_folder_list }}"
|
||||
- "{{ venv_install_destination_path in _target_folder_list }}"
|
||||
|
|
|
@ -16,14 +16,38 @@
|
|||
- name: Prepare the host/containers
|
||||
include: common/test-setup-host.yml
|
||||
|
||||
- name: Verify that the role works with a serial playbook
|
||||
include: test-functional.yml
|
||||
- name: Verify building on a web server, and installing using a URL
|
||||
import_playbook: test-functional.yml
|
||||
vars:
|
||||
target_host_group_name: test1
|
||||
target_serial: 1
|
||||
build_host: container1
|
||||
install_hosts: "container2:container3"
|
||||
venv_pip_packages:
|
||||
- "Jinja2==2.10"
|
||||
venv_install_destination_path: "{{ lookup('env', 'HOME') }}/venvs/test-venv"
|
||||
|
||||
- name: Verify that the role works with a parallel playbook
|
||||
include: test-functional.yml
|
||||
- name: Verify building on localhost, and installing using a copy
|
||||
import_playbook: test-functional.yml
|
||||
vars:
|
||||
target_host_group_name: test2
|
||||
target_serial: "100%"
|
||||
build_host: localhost
|
||||
install_hosts: "container1:container2:container3"
|
||||
venv_pip_packages:
|
||||
- "Jinja2==2.10"
|
||||
venv_install_destination_path: "{{ lookup('env', 'HOME') }}/venvs/test-venv"
|
||||
|
||||
- name: Verify building on a build host, and installing using a copy
|
||||
import_playbook: test-functional.yml
|
||||
vars:
|
||||
build_host: container2
|
||||
install_hosts: "container1:container3"
|
||||
venv_pip_packages:
|
||||
- "Jinja2==2.10"
|
||||
venv_install_destination_path: "{{ lookup('env', 'HOME') }}/venvs/test-venv"
|
||||
|
||||
- name: Verify setting multiple build hosts behaves correctly
|
||||
import_playbook: test-functional.yml
|
||||
vars:
|
||||
build_host: "localhost:container1"
|
||||
install_hosts: "container2:container3"
|
||||
venv_pip_packages:
|
||||
- "Jinja2==2.10"
|
||||
venv_install_destination_path: "{{ lookup('env', 'HOME') }}/venvs/test-venv"
|
||||
|
|
2
tox.ini
2
tox.ini
|
@ -28,6 +28,8 @@ setenv =
|
|||
ROLE_NAME=python_venv_build
|
||||
VIRTUAL_ENV={envdir}
|
||||
WORKING_DIR={toxinidir}
|
||||
# TODO(odyssey4me): remove after debugging is completed
|
||||
ANSIBLE_PARAMETERS=-v
|
||||
|
||||
|
||||
[testenv:docs]
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
# Copyright 2018, Rackspace US, Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
# NOTE(hwoarang): ansible_distribution may return a string with spaces
|
||||
# such as "openSUSE Leap" so we need to replace the space with underscore
|
||||
# in order to create a more sensible repo name for the distro.
|
||||
venv_distro_arch_grouping: "{{ (ansible_distribution | lower) | replace(' ', '_') }}-{{ ansible_distribution_version.split('.')[:2] | join('.') }}-{{ ansible_architecture | lower }}"
|
Loading…
Reference in New Issue