Create Ansible role to install arbitrary Python version
The purpose of this is to be able to install a version of python that is not available on target node. It downloads source code from Python site, compiles it using default compiler and install it. It also installs and upgrade python packages (pip, setuptools, etc.) and install additional ones required by user via Pip Change-Id: I3212d6fc1872451942aaa82e613236351f8592a3changes/47/697247/10
parent
d2741460ff
commit
9a76b8f9f0
@ -0,0 +1,4 @@
|
||||
---
|
||||
|
||||
skip_list:
|
||||
- '403'
|
@ -0,0 +1 @@
|
||||
tox-py38
|
@ -0,0 +1,94 @@
|
||||
# -*- mode: ruby -*-
|
||||
# vi: set ft=ruby :
|
||||
|
||||
# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
|
||||
VAGRANTFILE_API_VERSION = "2"
|
||||
|
||||
# Customize the count of CPU cores on the VM
|
||||
CPUS = 4
|
||||
|
||||
# Customize the amount of memory on the VM
|
||||
MEMORY = 8192
|
||||
|
||||
# Every Vagrant development environment requires a box. You can search for
|
||||
# boxes at https://vagrantcloud.com/search.
|
||||
BOX = "generic/centos7"
|
||||
|
||||
HOSTNAME = "tobiko"
|
||||
|
||||
TOX_INI_DIR = '../..'
|
||||
|
||||
|
||||
# All Vagrant configuration is done below. The "2" in Vagrant.configure
|
||||
# configures the configuration version (we support older styles for
|
||||
# backwards compatibility). Please don't change it unless you know what
|
||||
# you're doing.
|
||||
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||
# The most common configuration options are documented and commented below.
|
||||
# For a complete reference, please see the online documentation at
|
||||
# https://docs.vagrantup.com.
|
||||
|
||||
config.vm.box = BOX
|
||||
config.vm.hostname = HOSTNAME
|
||||
|
||||
# Disable automatic box update checking. If you disable this, then
|
||||
# boxes will only be checked for updates when the user runs
|
||||
# `vagrant box outdated`. This is not recommended.
|
||||
config.vm.box_check_update = false
|
||||
|
||||
# Create a forwarded port mapping which allows access to a specific port
|
||||
# within the machine from a port on the host machine. In the example below,
|
||||
# accessing "localhost:8080" will access port 80 on the guest machine.
|
||||
# NOTE: This will enable public access to the opened port
|
||||
# config.vm.network "forwarded_port", guest: 80, host: 8080
|
||||
|
||||
# Create a forwarded port mapping which allows access to a specific port
|
||||
# within the machine from a port on the host machine and only allow access
|
||||
# via 127.0.0.1 to disable public access
|
||||
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1"
|
||||
|
||||
# Create a private network, which allows host-only access to the machine
|
||||
# using a specific IP.
|
||||
# config.vm.network "private_network", ip: DEVSTACK_HOST_IP
|
||||
|
||||
# Create a public network, which generally matched to bridged network.
|
||||
# Bridged networks make the machine appear as another physical device on
|
||||
# your network.
|
||||
# config.vm.network "public_network", ip: "172.18.161.6"
|
||||
|
||||
# Share an additional folder to the guest VM. The first argument is
|
||||
# the path on the host to the actual folder. The second argument is
|
||||
# the path on the guest to mount the folder. And the optional third
|
||||
# argument is a set of non-required options.
|
||||
# config.vm.synced_folder "../data", "/vagrant_data"
|
||||
|
||||
# Provider-specific configuration so you can fine-tune various
|
||||
# backing providers for Vagrant. These expose provider-specific options.
|
||||
# Example for VirtualBox:
|
||||
|
||||
config.vm.provider "virtualbox" do |vb|
|
||||
# Display the VirtualBox GUI when booting the machine
|
||||
vb.gui = false
|
||||
|
||||
vb.cpus = CPUS
|
||||
vb.memory = MEMORY
|
||||
end
|
||||
|
||||
config.vm.provider "libvirt" do |libvirt|
|
||||
libvirt.cpus = CPUS
|
||||
libvirt.memory = MEMORY
|
||||
end
|
||||
|
||||
# No need to copy tox.ini folder to nodes to execute test cases
|
||||
config.vm.synced_folder TOX_INI_DIR, "/vagrant", type: "rsync",
|
||||
rsync__exclude: [".tox/"]
|
||||
|
||||
config.vm.provision "ansible" do |ansible|
|
||||
ansible.playbook = "resolv_conf.yaml"
|
||||
end
|
||||
|
||||
config.vm.provision "ansible" do |ansible|
|
||||
ansible.playbook = "tox-py38.yaml"
|
||||
end
|
||||
|
||||
end
|
@ -0,0 +1,3 @@
|
||||
[default]
|
||||
# human-readable stdout/stderr results display
|
||||
stdout_callback = debug
|
@ -0,0 +1,31 @@
|
||||
python_release: "3.8.0"
|
||||
python_version: "3.8"
|
||||
python_command: "python{{ python_version }}"
|
||||
python_name: "Python-{{ python_release }}"
|
||||
python_prefix: "/opt/{{ python_name }}"
|
||||
python_executable: "{{ python_prefix }}/bin/{{ python_command }}"
|
||||
python_url: "https://www.python.org/ftp/python/{{ python_release }}/{{ python_name }}.tgz"
|
||||
python_tar: "{{ ansible_env.HOME }}/{{ python_url | basename }}"
|
||||
python_src_dir: "{{ ansible_env.HOME }}/{{ python_name }}"
|
||||
|
||||
pip_command: "pip{{ python_version }}"
|
||||
pip_executable: "{{ python_prefix }}/bin/{{ pip_command }}"
|
||||
pip_url: "https://bootstrap.pypa.io/get-pip.py"
|
||||
pip_installer: "{{ ansible_env.HOME }}/{{ pip_url | basename }}"
|
||||
|
||||
profile_file: "/etc/profile.d/{{ python_name }}.sh"
|
||||
make_jobs: "{{ ansible_processor_vcpus }}"
|
||||
|
||||
yum_install_packages:
|
||||
- "@Development tools"
|
||||
- zlib-devel
|
||||
- openssl-devel
|
||||
- bzip2-devel
|
||||
- libffi-devel
|
||||
|
||||
pip_install_base_packages:
|
||||
- setuptools
|
||||
- pip
|
||||
- wheel
|
||||
|
||||
pip_install_packages: []
|
@ -0,0 +1,13 @@
|
||||
---
|
||||
|
||||
- hosts: all
|
||||
tasks:
|
||||
- name: Copy /etc/resolv.conf
|
||||
become: yes
|
||||
become_user: root
|
||||
copy:
|
||||
src: /etc/resolv.conf
|
||||
dest: /etc/resolv.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
@ -0,0 +1,105 @@
|
||||
---
|
||||
|
||||
- block:
|
||||
- name: check '{{ python_executable }}' is installed
|
||||
shell: |
|
||||
'{{ python_executable }}' --version 2>&1 | \
|
||||
grep 'Python {{ python_version}}'
|
||||
changed_when: false
|
||||
|
||||
rescue:
|
||||
- name: install '{{ python_name }}' build requeirements
|
||||
become: yes
|
||||
become_user: root
|
||||
yum:
|
||||
state: present
|
||||
name: '{{ yum_install_packages }}'
|
||||
when: "(yum_install_packages | length) > 0"
|
||||
|
||||
- name: download '{{ python_name }}' from '{{ python_url }}'
|
||||
get_url:
|
||||
url: "{{ python_url }}"
|
||||
dest: "{{ python_tar }}"
|
||||
|
||||
- name: ensure '{{ python_src_dir | dirname }}' directory exists
|
||||
file:
|
||||
path: '{{ python_src_dir }}'
|
||||
state: directory
|
||||
|
||||
- name: extract '{{ python_tar | basename }}' into '{{ python_src_dir }}'
|
||||
unarchive:
|
||||
src: '{{ python_tar }}'
|
||||
dest: '{{ python_src_dir | dirname }}'
|
||||
remote_src: yes
|
||||
|
||||
- name: configure '{{ python_name }}'
|
||||
command:
|
||||
cmd: './configure "--prefix={{ python_prefix }}"'
|
||||
chdir: '{{ python_src_dir }}'
|
||||
|
||||
- name: compile '{{ python_name }}'
|
||||
command:
|
||||
cmd: 'make -j {{ make_jobs }}'
|
||||
chdir: '{{ python_src_dir }}'
|
||||
|
||||
- name: install '{{ python_name }}'
|
||||
become: yes
|
||||
become_user: root
|
||||
command:
|
||||
cmd: 'make install'
|
||||
chdir: '{{ python_src_dir }}'
|
||||
|
||||
- name: check '{{ python_executable }}' is installed
|
||||
shell: |
|
||||
'{{ python_executable }}' --version 2>&1 | \
|
||||
grep 'Python {{ python_version}}'
|
||||
changed_when: false
|
||||
|
||||
|
||||
- block:
|
||||
- name: check '{{ pip_executable }}' is installed
|
||||
command: "'{{ pip_executable }}' --version"
|
||||
changed_when: false
|
||||
|
||||
rescue:
|
||||
|
||||
|
||||
- name: download Pip installer from '{{ pip_url }}'
|
||||
get_url:
|
||||
url: "{{ pip_url }}"
|
||||
dest: "{{ pip_installer }}"
|
||||
|
||||
- name: "Install '{{ pip_executable }}'"
|
||||
become: yes
|
||||
become_user: root
|
||||
command: "'{{ python_executable }}' '{{ pip_installer }}'"
|
||||
|
||||
- name: check Pip is installed for '{{ pip_executable }}'
|
||||
command: "'{{ pip_executable }}' --version"
|
||||
changed_when: false
|
||||
|
||||
|
||||
- name: "ensure base Python packages are installed and up-to-date"
|
||||
become: true
|
||||
become_user: root
|
||||
pip:
|
||||
executable: '{{ pip_executable }}'
|
||||
state: latest
|
||||
name: "{{ item }}"
|
||||
vars:
|
||||
ansible_python_interpreter: '{{ python_executable }}'
|
||||
when: (item | length ) > 0
|
||||
loop:
|
||||
- "{{ pip_install_base_packages }}"
|
||||
- "{{ pip_install_packages }}"
|
||||
|
||||
|
||||
- name: add '{{ profile_file }}'
|
||||
become: yes
|
||||
become_user: root
|
||||
template:
|
||||
src: profile.sh.j2
|
||||
dest: '{{ profile_file }}'
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
@ -0,0 +1 @@
|
||||
PATH={{ python_executable | dirname }}:$PATH
|
@ -0,0 +1,42 @@
|
||||
---
|
||||
|
||||
- hosts: all
|
||||
roles:
|
||||
- role: .
|
||||
vars:
|
||||
python_version: "3.8"
|
||||
python_release: "3.8.0"
|
||||
pip_install_packages:
|
||||
- virtualenv
|
||||
- tox
|
||||
|
||||
tasks:
|
||||
- name: run test cases
|
||||
shell:
|
||||
cmd: tox -e py38
|
||||
chdir: /vagrant
|
||||
register: run_test_cases
|
||||
ignore_errors: true
|
||||
|
||||
- name: produce test reports
|
||||
shell:
|
||||
cmd: tox -e report 2>&1
|
||||
chdir: /vagrant
|
||||
|
||||
- name: get test reports
|
||||
fetch:
|
||||
src: "/vagrant/{{ item }}"
|
||||
dest: "{{ playbook_dir }}/tox-py38/{{ inventory_hostname }}/{{ item }}"
|
||||
flat: yes
|
||||
loop:
|
||||
- tobiko_results.html
|
||||
|
||||
- name: check test cases result
|
||||
assert:
|
||||
that: run_test_cases.rc == 0
|
||||
fail_msg: |
|
||||
Test cases failed
|
||||
{{ run_test_cases.stdout }}
|
||||
success_msg: |
|
||||
Test cases passed
|
||||
{{ run_test_cases.stdout }}
|
Loading…
Reference in New Issue