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: I3212d6fc1872451942aaa82e613236351f8592a3
This commit is contained in:
parent
d2741460ff
commit
9a76b8f9f0
4
.ansible-lint
Normal file
4
.ansible-lint
Normal file
@ -0,0 +1,4 @@
|
||||
---
|
||||
|
||||
skip_list:
|
||||
- '403'
|
1
roles/python/.gitignore
vendored
Normal file
1
roles/python/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
tox-py38
|
94
roles/python/Vagrantfile
vendored
Normal file
94
roles/python/Vagrantfile
vendored
Normal file
@ -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
|
3
roles/python/ansible.cfg
Normal file
3
roles/python/ansible.cfg
Normal file
@ -0,0 +1,3 @@
|
||||
[default]
|
||||
# human-readable stdout/stderr results display
|
||||
stdout_callback = debug
|
31
roles/python/defaults/main.yaml
Normal file
31
roles/python/defaults/main.yaml
Normal file
@ -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: []
|
13
roles/python/resolv_conf.yaml
Normal file
13
roles/python/resolv_conf.yaml
Normal file
@ -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'
|
105
roles/python/tasks/main.yaml
Normal file
105
roles/python/tasks/main.yaml
Normal file
@ -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'
|
1
roles/python/templates/profile.sh.j2
Normal file
1
roles/python/templates/profile.sh.j2
Normal file
@ -0,0 +1 @@
|
||||
PATH={{ python_executable | dirname }}:$PATH
|
42
roles/python/tox-py38.yaml
Normal file
42
roles/python/tox-py38.yaml
Normal file
@ -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…
x
Reference in New Issue
Block a user