Revise the role to properly cater to use-cases

1. Variables have been renamed to make it easier to
   understand their purpose.
2. Unnecessary variables have been removed.
3. The role no longer caters to installing pip packages
   on the host. This should never be necessary - if it
   is, then something should do so beforehand.
4. The expected versions of pip/virtualenv are documented
   and a check has been added to ensure that they exist.
5. The handler has been named to make debug logs less
   confusing.
6. The default storage path for venvs/wheels is no longer
   opinionated. If paths based on distro/architecture are
   required then different paths should be provided to
   the role.

Change-Id: I9eb96e9db22f918b00456af943d81f66050107ce
This commit is contained in:
Jesse Pretorius 2018-04-27 15:15:40 +01:00
parent 19e2573be8
commit d169906c68
12 changed files with 347 additions and 258 deletions

View File

@ -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/

View File

@ -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.

View File

@ -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

View File

@ -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 != []

View File

@ -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'

View File

@ -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 \

View File

@ -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

View File

@ -3,18 +3,8 @@ localhost
container1
container2
container3
container4
[all_containers]
container1
container2
container3
container4
[test1]
container1
container2
[test2]
container3
container4

View File

@ -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 }}"

View File

@ -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"

View File

@ -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]

19
vars/main.yml Normal file
View File

@ -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 }}"