Skip to content
Snippets Groups Projects
Commit 5fc7ad68 authored by Chris Coley's avatar Chris Coley
Browse files

Update the bootstrap tasks to fail if Python is not available

Initially, this role would check if Python was available in the default location
of '/usr/bin/python', and would install Python 2 if it wasn't. I didn't like the
idea of installing Python 2 so I updated the role to look for a usable Python
interpreter in other standard locations, including Python 3's default location
of '/usr/bin/python3'. Then it would tell the user to set
'ansible_python_interpreter' to one of the interpreters it found. I liked this
because it gave the user the choice of how to resolve the issue. However, this
role was running all the Python finding/checking tasks for every host and that
struck me as inefficient, so I changed it.

Now, the role checks if the host is pingable. If it is not, then it runs tasks
to determine why that specific host is not pingable. It then relays that
information to the user by failing out with the fail module and a descriptive
message. Hosts that are pingable do not run these tasks.
parent 51ade85c
Branches
No related tags found
No related merge requests found
......@@ -15,12 +15,5 @@ common_utils:
- screen
- unzip
- vim
# The path to the python executable to use
# If set and the path is executable, then it will be used.
# Else if Python 2 is executable, use it.
# Else if Python 3 is executable, use if.
# Else, fail.
ansible_python_interpreter:
...
# vi: set ts=2 sts=2 sw=2 et ft=yaml:
---
- name: Bootstrap the host by selecting which Python interpreter to use, and other OS specific stuff
- name: Bootstrap the host by making sure the host is pingable and installing OS specific requirements
tags: bootstrap
block:
# If ansible_python_interpreter is set and exists, use it.
# Elif python 2 exists, use it.
# Elif python 3 exists, use it.
# Else, fail.
- name: Figure out which version of Python to use
when: ansible_python_interpreter is not defined or not ansible_python_interpreter
block:
- name: Check if /usr/bin/python is executable
raw: 'test -x /usr/bin/python'
changed_when: false
failed_when: false
register: python_default
- name: Set 'ansible_python_interpreter' to /usr/bin/python
when: python_default.rc is defined and python_default.rc == 0
set_fact:
ansible_python_interpreter: /usr/bin/python
- name: Check if /usr/bin/python2 is executable
raw: 'test -x /usr/bin/python2'
changed_when: false
failed_when: false
register: python_2
- name: Set 'ansible_python_interpreter' to /usr/bin/python2
when: python_2.rc is defined and python_2.rc == 0
set_fact:
ansible_python_interpreter: /usr/bin/python2
- name: Check if /usr/bin/python3 is executable
raw: 'test -x /usr/bin/python3'
changed_when: false
failed_when: false
register: python_3
- name: Set 'ansible_python_interpreter' to /usr/bin/python3
when: python_3.rc is defined and python_3.rc == 0
set_fact:
ansible_python_interpreter: /usr/bin/python3
# - debug:
# var: ansible_python_interpreter
- name: Check if 'ansible_python_interpreter' is executable
raw: 'test -x {{ ansible_python_interpreter }}'
changed_when: false
- name: Check if the host is pingable
ping:
register: _can_ping
failed_when: false
register: python_executable
- name: Assert that 'ansible_python_interpreter' is executable
assert:
that:
- ansible_python_interpreter is defined and ansible_python_interpreter
- python_executable.rc is defined and python_executable.rc == 0
# - name: Install Python
# raw: >
# (test -e /etc/redhat-release && yum install -y python)
# || (test -e /etc/debian_version && apt-get -y update && apt-get install -y python)
# when: result.rc is defined and result.rc == 1
- name: If the host is not pingable, find out why
include_tasks: tasks/diagnose-unpingable.yml
when: _can_ping.ping is not defined or _can_ping.ping != 'pong'
- name: Gather facts to determine host OS
- name: Gather minimal facts to determine host OS
setup:
gather_subset: min
......@@ -74,7 +26,8 @@
- vars/{{ ansible_os_family | lower }}.yml
skip: true
- include_tasks: '{{ item }}'
- name: Include OS specific bootstrap tasks
include_tasks: '{{ item }}'
with_first_found:
- tasks/bootstrap_{{ ansible_distribution | lower }}-{{ ansible_distribution_version | lower }}.yml
- tasks/bootstrap_{{ ansible_distribution | lower }}-{{ ansible_distribution_release | lower }}.yml
......
#
# This task list attempts to diagnose why a host is not pingable with Ansible's
# built-in ping module. It is currently able to diagnose issues with Python
# being unavailable, or Python being an unsupported version.
#
---
# If the error has a defined error message and is not related to Python not
# being found, then display that message
- fail:
msg: '{{ _can_ping.msg }}'
when: _can_ping.msg is defined and (_can_ping.rc is not defined or _can_ping.rc != 127)
# If the error is related to Python not being found, then try to find the
# available Python interpreters
- name: Python is not found
when: _can_ping.rc is defined and _can_ping.rc == 127
block:
- include_tasks: tasks/find-python-executable.yml
- fail:
msg: "Unable to find Python on {{ inventory_hostname }}.\n
Please set 'ansible_python_interpreter' to an executable Python interpreter.\n
The host has these available: ( {{ _python_interpreters | join(' , ') }} )"
# This block is a catchall that runs whenever an unanticipated error occurs
- name: Something Unexpected Happened
block:
- debug:
var: _can_ping
- fail:
msg: Something Unexpected Happened
...
# vi: set ts=2 sts=2 sw=2 et ft=yaml:
#
# This task list atempts to find all the available Python interpreters on a host
# and build a list of them in a variable called '_python_interpreters'.
#
---
- block:
# Initialize an empty list of available interpreters
- set_fact:
_python_interpreters: []
# Loop through the common interpreter paths, testing if they are available
- name: Find a usable Python interpreter
include_tasks: tasks/test-python-executable.yml
loop_control:
loop_var: _python_path
with_items:
- /usr/bin/python
- /usr/bin/python2
- /usr/bin/python3
...
# vi: set ts=2 sts=2 sw=2 et ft=yaml:
#
# This task list tests is a python interpreter path is executable, and appends
# it to a list of executable paths if it is. Ansible has version requirements
# for Python interpreters, but this task list doesn't check for those.
#
# Parameters:
# _python_path An absolute path to a Python interpreter.
# _python_interpreters A list to append executable paths to.
#
---
- name: Check if '{{ _python_path }}' is executable
raw: 'test -x {{ _python_path }}'
changed_when: false
failed_when: false
register: __can_exec
- name: If '{{ _python_path }}' is executable, append it to the list of available interpreters
set_fact:
_python_interpreters: "{{ _python_interpreters }} + [ '{{ _python_path }}' ]"
when: __can_exec.rc is defined and __can_exec.rc == 0
...
# vi: set ts=2 sts=2 sw=2 et ft=yaml:
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment