Skip to content

Commit a18ce1e

Browse files
committed
refuse to continue when ap uses py 2
Fixes #80 Signed-off-by: Tomas Tomecek <[email protected]>
1 parent 1f005b0 commit a18ce1e

File tree

5 files changed

+84
-4
lines changed

5 files changed

+84
-4
lines changed

ansible_bender/core.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@
4545
from ansible_bender.conf import ImageMetadata, Build
4646
from ansible_bender.constants import TIMESTAMP_FORMAT
4747
from ansible_bender.exceptions import AbBuildUnsuccesful
48-
from ansible_bender.utils import run_cmd, ap_command_exists, random_str, graceful_get
48+
from ansible_bender.utils import run_cmd, ap_command_exists, random_str, graceful_get, \
49+
is_ansibles_python_2
4950

5051
logger = logging.getLogger(__name__)
5152
A_CFG_TEMPLATE = """\
@@ -78,6 +79,12 @@ def run_playbook(playbook_path, inventory_path, a_cfg_path, connection, extra_va
7879
:return: output
7980
"""
8081
ap = ap_command_exists()
82+
if is_ansibles_python_2(ap):
83+
raise RuntimeError(
84+
"ansible-bender is written in python 3 and does not work in python 2,\n"
85+
f"it seems that {ap} is using python 2 - ansible-bender will not"
86+
"work in such environment\n"
87+
)
8188
cmd_args = [
8289
ap,
8390
"-c", connection,

ansible_bender/utils.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import logging
55
import os
66
import random
7+
import re
78
import shutil
89
import string
910
import subprocess
@@ -126,14 +127,14 @@ def env_get_or_fail_with(env_name, err_msg):
126127
raise RuntimeError(err_msg)
127128

128129

129-
def one_of_commands_exists(commands, exc_msg):
130+
def one_of_commands_exists(commands, exc_msg) -> str:
130131
"""
131132
Verify that the provided command exists. Raise CommandDoesNotExistException in case of an
132133
error or if the command does not exist.
133134
134135
:param commands: str, command to check (python 3 only)
135136
:param exc_msg: str, message of exception when command does not exist
136-
:return: bool, True if everything's all right (otherwise exception is thrown)
137+
:return: str, the command which exists
137138
"""
138139
found = False
139140
for command in commands:
@@ -233,3 +234,29 @@ def random_str(size=10):
233234
:return: the string
234235
"""
235236
return ''.join(random.choice(string.ascii_lowercase) for _ in range(size))
237+
238+
239+
def is_ansibles_python_2(ap_exe: str) -> bool:
240+
"""
241+
Discover whether ansible-playbook is using python 2.
242+
243+
:param ap_exe: path to the python executable
244+
245+
:return: True if it's 2
246+
"""
247+
out = run_cmd([ap_exe, "--version"], log_stderr=True, return_output=True)
248+
249+
# python version = 3.7.2
250+
reg = r"python version = (\d)"
251+
252+
reg_grp = re.findall(reg, out)
253+
try:
254+
py_version = reg_grp[0]
255+
except IndexError:
256+
logger.warning("could not figure out which python is %s using", ap_exe)
257+
return False # we don't know, fingers crossed
258+
if py_version == "2":
259+
logger.info("%s is using python 2", ap_exe)
260+
return True
261+
logger.debug("it seems that %s is not using python 2", ap_exe)
262+
return False

tests/integration/test_core.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
"""
2+
Tests for ansible invocation
3+
"""
4+
import pytest
5+
from flexmock import flexmock
6+
7+
from ansible_bender import utils
8+
from ansible_bender.core import run_playbook
9+
from tests.spellbook import C7_AP_VER_OUT
10+
11+
12+
def test_ansibles_python():
13+
flexmock(utils, run_cmd=lambda *args, **kwargs: C7_AP_VER_OUT),
14+
with pytest.raises(RuntimeError) as ex:
15+
run_playbook(None, None, None, None)
16+
assert str(ex.value).startswith(
17+
"ansible-bender is written in python 3 and does not work in python 2,\n")

tests/spellbook.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,15 @@
3131
bad_playbook_path = os.path.join(data_dir, "bad_playbook.yaml")
3232
base_image = "docker.io/library/python:3-alpine"
3333

34+
C7_AP_VER_OUT = """\
35+
ansible-playbook 2.4.2.0
36+
config file = /etc/ansible/ansible.cfg
37+
configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
38+
ansible python module location = /usr/lib/python2.7/site-packages/ansible
39+
executable location = /usr/bin/ansible-playbook
40+
python version = 2.7.5 (default, Oct 30 2018, 23:45:53) [GCC 4.8.5 20150623 (Red Hat 4.8.5-36)]
41+
"""
42+
3443

3544
def random_word(length):
3645
# https://stackoverflow.com/a/2030081/909579

tests/unit/test_utils.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
import re
22

33
import pytest
4+
from flexmock import flexmock
45

6+
from ansible_bender import utils
57
from ansible_bender.db import generate_working_cont_name
6-
from ansible_bender.utils import run_cmd, graceful_get
8+
from ansible_bender.utils import run_cmd, graceful_get, ap_command_exists, is_ansibles_python_2
9+
from tests.spellbook import C7_AP_VER_OUT
710

811

912
def test_run_cmd():
@@ -39,3 +42,20 @@ def test_graceful_g_w_default():
3942
assert graceful_get(inp, 1, default="asd") == {2: 3}
4043
assert graceful_get(inp, 1, 2, default="asd") == 3
4144
assert graceful_get(inp, 1, 2, 4, default="asd") == "asd"
45+
46+
47+
@pytest.mark.parametrize("m,is_py2", (
48+
(object, False), # no mocking
49+
(
50+
lambda: flexmock(utils, run_cmd=lambda *args, **kwargs: C7_AP_VER_OUT),
51+
True
52+
),
53+
(
54+
lambda: flexmock(utils, run_cmd=lambda *args, **kwargs: "nope"),
55+
False
56+
),
57+
))
58+
def test_ansibles_python(m, is_py2):
59+
m()
60+
cmd = ap_command_exists()
61+
assert is_ansibles_python_2(cmd) == is_py2

0 commit comments

Comments
 (0)