Skip to content

Commit 86c4857

Browse files
authored
Merge pull request #1 from volcan01010/centos7-python2
Add first draft CentOS 7 - Python 2
2 parents 17ec835 + 9323114 commit 86c4857

File tree

1 file changed

+106
-0
lines changed

1 file changed

+106
-0
lines changed
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
---
2+
title: "CentOS 7, Ansible and the end of Python 2"
3+
author: Dr John A Stevenson
4+
categories:
5+
- devops
6+
tags:
7+
- Python
8+
- CentOS
9+
- Ansible
10+
- continuous-integration
11+
---
12+
13+
The [sunsetting of Python 2](https://www.python.org/doc/sunset-python-2/) on 1 January 2020 has started to cause problems with administering our CentOS 7 servers.
14+
We use [Ansible](https://www.ansible.com/) for automatic configuration and
15+
a few of our long-running jobs recently began to fail as a result Python 2 / Python 3 mistmatches.
16+
Officially, CentOS 7 is [supported until
17+
2024-06-30](https://wiki.centos.org/About/Product), but I think the end of
18+
Python 2 will hasten its demise.
19+
20+
The notes below explain how we solved our issues with CentOS 7 and Ansible.
21+
Hopefully they will be helpful to others.
22+
23+
24+
## Background
25+
26+
When you configure a machine with Ansible, it connects to it via SSH and runs
27+
shell scripts and/or Python scripts to apply the settings that you requested.
28+
In CentOS 7, these scripts are run by Python 2.7.
29+
This causes the following problems with Python tools installed using the `pip`
30+
package manager.
31+
32+
33+
- An increasing number of packages are Python 3 only, and others e.g. `docker-compose`, are not being updated for Python 2. As Ansible's `pip` module uses the system Python 2 interpreter by default, it may fail or get an out-of-date version.
34+
- Other Ansible modules (e.g. `docker-compose, `nsupdate`), rely on Python
35+
libraries installed on the system. By default, Ansible will try to use
36+
the Python 2 version. Again, these may be old or may not even exist.
37+
38+
39+
## Making Ansible work with Python 3
40+
41+
The solution to this is to make Ansible use Python 3 on the target system. The
42+
following steps allow this:
43+
44+
### Ensure Python 3 and pip are present
45+
46+
The following tasks ensure the server is able to use Python 3.
47+
48+
```yaml
49+
---
50+
- name: Install latest python 3 and pip3
51+
yum:
52+
name:
53+
- python36
54+
- libselinux-python
55+
state: present
56+
57+
- name: Install SELinux for Python 3
58+
pip:
59+
name:
60+
- selinux
61+
state: present
62+
executable: pip3
63+
vars:
64+
ansible_python_interpreter: /usr/bin/python3
65+
```
66+
67+
Note that `pip3` is automatically installed with Python 3.6, and that the
68+
SELinux dependencies are required by some Ansible modules.
69+
70+
### Use pip3 to install packages
71+
72+
The Ansible `pip` module has a flag to specify `pip3`. Use this to install
73+
packages to the system's Python 3.
74+
75+
```yaml
76+
- name: Install ETLHelper
77+
pip:
78+
name:
79+
- etlhelper
80+
state: present
81+
executable: pip3
82+
```
83+
84+
### Tell Ansible to use Python 3 interpreter where required
85+
86+
Ansible uses the `ansible_python_interpreter` variable to define with Python to
87+
use. This must be specified wherever a module uses a Python 3 dependency e.g.
88+
89+
```yaml
90+
- name: Use dnsupdate to update ip host
91+
nsupdate:
92+
server: "{{ dns_server }}"
93+
zone: "{{ dns_path }}"
94+
record: "{{ ansible_hostname }}"
95+
value: "{{ ansible_default_ipv4.address }}"
96+
ttl: 600
97+
vars:
98+
ansible_python_interpreter: /usr/bin/python3
99+
```
100+
101+
Ansible reads variable definitions according to a [defined
102+
hierarchy](https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html#variable-precedence-where-should-i-put-a-variable).
103+
In the example above, the variable sets Python 3 as interpreter for a single
104+
task and Python 2 is used elsewhere. We find this preferable as it is most
105+
explicit and some other modules, most notably `yum`, will only work with Python
106+
2.

0 commit comments

Comments
 (0)