Skip to content

Commit

Permalink
Remove use of distutils
Browse files Browse the repository at this point in the history
  • Loading branch information
Shrews committed Jan 27, 2022
1 parent 996a00d commit 8040e41
Show file tree
Hide file tree
Showing 7 changed files with 23 additions and 48 deletions.
3 changes: 1 addition & 2 deletions ansible_runner/config/runner.py
Expand Up @@ -23,7 +23,6 @@
import stat
import tempfile
import six
import distutils.dir_util

from six import string_types, text_type

Expand Down Expand Up @@ -146,7 +145,7 @@ def prepare(self):
if os.path.exists(self.project_dir):
output.debug("Copying directory tree from {} to {} for working directory isolation".format(self.project_dir,
self.directory_isolation_path))
distutils.dir_util.copy_tree(self.project_dir, self.directory_isolation_path, preserve_symlinks=True)
shutil.copytree(self.project_dir, self.directory_isolation_path, symlinks=True)

self.prepare_inventory()
self.prepare_command()
Expand Down
4 changes: 1 addition & 3 deletions ansible_runner/utils/__init__.py
Expand Up @@ -17,8 +17,6 @@
import atexit
import signal

from distutils.spawn import find_executable

from ansible_runner.exceptions import ConfigurationError

try:
Expand Down Expand Up @@ -474,7 +472,7 @@ def sanitize_json_response(data):


def get_executable_path(name):
exec_path = find_executable(name)
exec_path = shutil.which(name)
if exec_path is None:
raise ConfigurationError(f"{name} command not found")
return exec_path
Expand Down
19 changes: 0 additions & 19 deletions test/conftest.py
@@ -1,8 +1,5 @@
import shutil

from distutils.version import LooseVersion
from pathlib import Path

from ansible_runner import defaults

import pkg_resources
Expand All @@ -25,16 +22,6 @@ def change_save_path(tmp_path, mocker):
mocker.patch.object(defaults, 'AUTO_CREATE_DIR', str(tmp_path))


@pytest.fixture(scope='session')
def is_pre_ansible28():
try:
if LooseVersion(pkg_resources.get_distribution('ansible').version) < LooseVersion('2.8'):
return True
except pkg_resources.DistributionNotFound:
# ansible-base (e.g. ansible 2.10 and beyond) is not accessible in this way
pass


@pytest.fixture(scope='session')
def is_pre_ansible211():
"""
Expand All @@ -51,12 +38,6 @@ def is_pre_ansible211():
return True


@pytest.fixture(scope='session')
def skipif_pre_ansible28(is_pre_ansible28):
if is_pre_ansible28:
pytest.skip("Valid only on Ansible 2.8+")


@pytest.fixture(scope='session')
def skipif_pre_ansible211(is_pre_ansible211):
if is_pre_ansible211:
Expand Down
4 changes: 2 additions & 2 deletions test/integration/test___main__.py
Expand Up @@ -98,7 +98,7 @@ def test_cmdline_role_with_playbook_option():
assert exc == 1


def test_cmdline_playbook(is_pre_ansible28, tmp_path):
def test_cmdline_playbook(tmp_path):
private_data_dir = tmp_path
play = [{'hosts': 'all', 'tasks': [{'debug': {'msg': random_string()}}]}]

Expand Down Expand Up @@ -142,7 +142,7 @@ def test_cmdline_includes_one_option():
assert exc == 1


def test_cmdline_cmdline_override(is_pre_ansible28, tmp_path):
def test_cmdline_cmdline_override(tmp_path):
private_data_dir = tmp_path
play = [{'hosts': 'all', 'tasks': [{'debug': {'msg': random_string()}}]}]

Expand Down
14 changes: 7 additions & 7 deletions test/integration/test_display_callback.py
Expand Up @@ -13,7 +13,7 @@


@pytest.fixture()
def executor(tmp_path, request, is_pre_ansible28):
def executor(tmp_path, request):
private_data_dir = tmp_path / 'foo'
private_data_dir.mkdir()

Expand Down Expand Up @@ -176,7 +176,7 @@ def test_callback_plugin_no_log_filters(executor, playbook):
- uri: url=https://example.org url_username="PUBLIC" url_password="PRIVATE"
'''}, # noqa
])
def test_callback_plugin_task_args_leak(executor, playbook, skipif_pre_ansible28):
def test_callback_plugin_task_args_leak(executor, playbook):
executor.run()
events = list(executor.events)
assert events[0]['event'] == 'playbook_on_start'
Expand Down Expand Up @@ -213,7 +213,7 @@ def test_callback_plugin_task_args_leak(executor, playbook, skipif_pre_ansible28
- debug: msg="{{ command_register.results|map(attribute='stdout')|list }}"
'''}, # noqa
])
def test_callback_plugin_censoring_does_not_overwrite(executor, playbook, skipif_pre_ansible28):
def test_callback_plugin_censoring_does_not_overwrite(executor, playbook):
executor.run()
events = list(executor.events)
assert events[0]['event'] == 'playbook_on_start'
Expand Down Expand Up @@ -258,7 +258,7 @@ def test_callback_plugin_strips_task_environ_variables(executor, playbook):
foo: "bar"
'''}, # noqa
])
def test_callback_plugin_saves_custom_stats(executor, playbook, skipif_pre_ansible28):
def test_callback_plugin_saves_custom_stats(executor, playbook):
executor.run()
for event in executor.events:
event_data = event.get('event_data', {})
Expand All @@ -284,7 +284,7 @@ def test_callback_plugin_saves_custom_stats(executor, playbook, skipif_pre_ansib
- my_handler
'''}, # noqa
])
def test_callback_plugin_records_notify_events(executor, playbook, skipif_pre_ansible28):
def test_callback_plugin_records_notify_events(executor, playbook):
executor.run()
assert len(list(executor.events))
notify_events = [x for x in executor.events if x['event'] == 'playbook_on_notify']
Expand All @@ -308,7 +308,7 @@ def test_callback_plugin_records_notify_events(executor, playbook, skipif_pre_an
url_password: "{{ pw }}"
'''}, # noqa
])
def test_module_level_no_log(executor, playbook, skipif_pre_ansible28):
def test_module_level_no_log(executor, playbook):
# It's possible for `no_log=True` to be defined at the _module_ level,
# e.g., for the URI module password parameter
# This test ensures that we properly redact those
Expand Down Expand Up @@ -398,7 +398,7 @@ def test_output_when_given_non_playbook_script(tmp_path):
msg: "{{ ('F' * 150) | list }}"
'''}, # noqa
])
def test_large_stdout_parsing_when_using_json_output(executor, playbook, skipif_pre_ansible28):
def test_large_stdout_parsing_when_using_json_output(executor, playbook):
# When the json flag is used, it is possible to output more data than
# pexpect's maxread default of 2000 characters. As a result, if not
# handled properly, the stdout can end up being corrupted with partial
Expand Down
25 changes: 11 additions & 14 deletions test/integration/test_events.py
@@ -1,16 +1,15 @@
import os
import json

from distutils.spawn import find_executable

import shutil
import pytest

from ansible_runner import defaults, run, run_async


@pytest.mark.test_all_runtimes
@pytest.mark.parametrize('containerized', [True, False])
def test_basic_events(containerized, is_pre_ansible28, runtime, tmp_path, is_run_async=False, g_facts=False):
def test_basic_events(containerized, runtime, tmp_path, is_run_async=False, g_facts=False):

inventory = 'localhost ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"'

Expand Down Expand Up @@ -56,11 +55,11 @@ def test_basic_events(containerized, is_pre_ansible28, runtime, tmp_path, is_run

@pytest.mark.test_all_runtimes
@pytest.mark.parametrize('containerized', [True, False])
def test_async_events(containerized, is_pre_ansible28, runtime, tmp_path):
test_basic_events(containerized, is_pre_ansible28, runtime, tmp_path, is_run_async=True, g_facts=True)
def test_async_events(containerized, runtime, tmp_path):
test_basic_events(containerized, runtime, tmp_path, is_run_async=True, g_facts=True)


def test_basic_serializeable(is_pre_ansible28, tmp_path):
def test_basic_serializeable(tmp_path):
inv = 'localhost ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"'
r = run(private_data_dir=str(tmp_path),
inventory=inv,
Expand All @@ -69,7 +68,7 @@ def test_basic_serializeable(is_pre_ansible28, tmp_path):
json.dumps(events)


def test_event_omission(is_pre_ansible28, tmp_path):
def test_event_omission(tmp_path):
inv = 'localhost ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"'
r = run(private_data_dir=str(tmp_path),
inventory=inv,
Expand All @@ -86,7 +85,7 @@ def test_event_omission(is_pre_ansible28, tmp_path):
assert not any([x['event_data'] for x in events])


def test_event_omission_except_failed(is_pre_ansible28, tmp_path):
def test_event_omission_except_failed(tmp_path):
inv = 'localhost ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"'
r = run(private_data_dir=str(tmp_path),
inventory=inv,
Expand All @@ -105,7 +104,7 @@ def test_event_omission_except_failed(is_pre_ansible28, tmp_path):
assert len(all_event_datas) == 1


def test_runner_on_start(rc, skipif_pre_ansible28, tmp_path):
def test_runner_on_start(rc, tmp_path):
r = run(private_data_dir=str(tmp_path),
inventory='localhost ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"',
playbook=[{'hosts': 'all', 'gather_facts': False, 'tasks': [{'debug': {'msg': "test"}}]}])
Expand All @@ -114,9 +113,7 @@ def test_runner_on_start(rc, skipif_pre_ansible28, tmp_path):
assert len(start_events) == 1


def test_playbook_on_stats_summary_fields(project_fixtures, is_pre_ansible28):
if is_pre_ansible28:
pytest.skip('Test is for post 2.8 status types.')
def test_playbook_on_stats_summary_fields(project_fixtures):
private_data_dir = project_fixtures / 'host_status'

res = run(
Expand Down Expand Up @@ -147,9 +144,9 @@ def test_include_role_events(project_fixtures):
assert event_data['res']['msg'] == 'Hello world!'


@pytest.mark.skipif(find_executable('cgexec') is None,
@pytest.mark.skipif(shutil.which('cgexec') is None,
reason="cgexec not available")
def test_profile_data(skipif_pre_ansible28, tmp_path):
def test_profile_data(tmp_path):
try:
r = run(private_data_dir=str(tmp_path),
inventory='localhost ansible_connection=local ansible_python_interpreter="{{ ansible_playbook_python }}"',
Expand Down
2 changes: 1 addition & 1 deletion test/unit/config/test_runner.py
Expand Up @@ -223,7 +223,7 @@ def test_prepare_env_directory_isolation_from_settings(mocker, project_fixtures)
'''
# Mock away the things that would actually prepare the isolation directory.
mocker.patch('os.makedirs', return_value=True)
copy_tree = mocker.patch('distutils.dir_util.copy_tree')
copy_tree = mocker.patch('shutil.copytree')
mkdtemp = mocker.patch('tempfile.mkdtemp')
mkdtemp.return_value = '/tmp/runner/runner_di_XYZ'
mocker.patch('ansible_runner.config.runner.RunnerConfig.build_process_isolation_temp_dir')
Expand Down

0 comments on commit 8040e41

Please sign in to comment.