diff --git a/changelogs/fragments/3934-distutils.yml b/changelogs/fragments/3934-distutils.yml new file mode 100644 index 0000000000..4b75b83ba7 --- /dev/null +++ b/changelogs/fragments/3934-distutils.yml @@ -0,0 +1,6 @@ +bugfixes: + - "say callback plugin - replace deprecated ``distutils.spawn.find_executable`` with Ansible's ``get_bin_path`` to find the ``say`` resp. ``espeak`` executables (https://github.com/ansible-collections/community.general/pull/3934)." + - "jail connection plugin - replace deprecated ``distutils.spawn.find_executable`` with Ansible's ``get_bin_path`` to find the executable (https://github.com/ansible-collections/community.general/pull/3934)." + - "lxd connection plugin - replace deprecated ``distutils.spawn.find_executable`` with Ansible's ``get_bin_path`` to find the ``lxc`` executable (https://github.com/ansible-collections/community.general/pull/3934)." + - "zone connection plugin - replace deprecated ``distutils.spawn.find_executable`` with Ansible's ``get_bin_path`` to find the executable (https://github.com/ansible-collections/community.general/pull/3934)." + - "passwordstore lookup plugin - replace deprecated ``distutils.util.strtobool`` with Ansible's ``convert_bool.boolean`` to interpret values for the ``create``, ``returnall``, ``overwrite``, 'backup``, and ``nosymbols`` options (https://github.com/ansible-collections/community.general/pull/3934)." diff --git a/plugins/callback/say.py b/plugins/callback/say.py index 8e8bd507a2..8d67e4336a 100644 --- a/plugins/callback/say.py +++ b/plugins/callback/say.py @@ -21,11 +21,11 @@ DOCUMENTATION = ''' - In 2.8, this callback has been renamed from C(osx_say) into M(community.general.say). ''' -import distutils.spawn import platform import subprocess import os +from ansible.module_utils.common.process import get_bin_path from ansible.plugins.callback import CallbackBase @@ -47,21 +47,24 @@ class CallbackModule(CallbackBase): self.HAPPY_VOICE = None self.LASER_VOICE = None - self.synthesizer = distutils.spawn.find_executable('say') - if not self.synthesizer: - self.synthesizer = distutils.spawn.find_executable('espeak') - if self.synthesizer: + try: + self.synthesizer = get_bin_path('say') + if platform.system() != 'Darwin': + # 'say' binary available, it might be GNUstep tool which doesn't support 'voice' parameter + self._display.warning("'say' executable found but system is '%s': ignoring voice parameter" % platform.system()) + else: + self.FAILED_VOICE = 'Zarvox' + self.REGULAR_VOICE = 'Trinoids' + self.HAPPY_VOICE = 'Cellos' + self.LASER_VOICE = 'Princess' + except ValueError: + try: + self.synthesizer = get_bin_path('espeak') self.FAILED_VOICE = 'klatt' self.HAPPY_VOICE = 'f5' self.LASER_VOICE = 'whisper' - elif platform.system() != 'Darwin': - # 'say' binary available, it might be GNUstep tool which doesn't support 'voice' parameter - self._display.warning("'say' executable found but system is '%s': ignoring voice parameter" % platform.system()) - else: - self.FAILED_VOICE = 'Zarvox' - self.REGULAR_VOICE = 'Trinoids' - self.HAPPY_VOICE = 'Cellos' - self.LASER_VOICE = 'Princess' + except ValueError: + self.synthesizer = None # plugin disable itself if say is not present # ansible will not call any callback if disabled is set to True diff --git a/plugins/connection/jail.py b/plugins/connection/jail.py index 02f5aeeddd..3c820be175 100644 --- a/plugins/connection/jail.py +++ b/plugins/connection/jail.py @@ -31,7 +31,6 @@ DOCUMENTATION = ''' - name: ansible_jail_user ''' -import distutils.spawn import os import os.path import subprocess @@ -39,6 +38,7 @@ import traceback from ansible.errors import AnsibleError from ansible.module_utils.six.moves import shlex_quote +from ansible.module_utils.common.process import get_bin_path from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text from ansible.plugins.connection import ConnectionBase, BUFSIZE from ansible.utils.display import Display @@ -75,10 +75,10 @@ class Connection(ConnectionBase): @staticmethod def _search_executable(executable): - cmd = distutils.spawn.find_executable(executable) - if not cmd: + try: + return get_bin_path(executable) + except ValueError: raise AnsibleError("%s command not found in PATH" % executable) - return cmd def list_jails(self): p = subprocess.Popen([self.jls_cmd, '-q', 'name'], diff --git a/plugins/connection/lxd.py b/plugins/connection/lxd.py index a964932b3f..f3b06e6e39 100644 --- a/plugins/connection/lxd.py +++ b/plugins/connection/lxd.py @@ -43,10 +43,10 @@ DOCUMENTATION = ''' ''' import os -from distutils.spawn import find_executable from subprocess import Popen, PIPE from ansible.errors import AnsibleError, AnsibleConnectionFailure, AnsibleFileNotFound +from ansible.module_utils.common.process import get_bin_path from ansible.module_utils.common.text.converters import to_bytes, to_text from ansible.plugins.connection import ConnectionBase @@ -62,9 +62,9 @@ class Connection(ConnectionBase): super(Connection, self).__init__(play_context, new_stdin, *args, **kwargs) self._host = self._play_context.remote_addr - self._lxc_cmd = find_executable("lxc") - - if not self._lxc_cmd: + try: + self._lxc_cmd = get_bin_path("lxc") + except ValueError: raise AnsibleError("lxc command not found in PATH") if self._play_context.remote_user is not None and self._play_context.remote_user != 'root': diff --git a/plugins/connection/zone.py b/plugins/connection/zone.py index 8fbcd8a038..d7e127ca38 100644 --- a/plugins/connection/zone.py +++ b/plugins/connection/zone.py @@ -26,7 +26,6 @@ DOCUMENTATION = ''' - name: ansible_zone_host ''' -import distutils.spawn import os import os.path import subprocess @@ -34,6 +33,7 @@ import traceback from ansible.errors import AnsibleError from ansible.module_utils.six.moves import shlex_quote +from ansible.module_utils.common.process import get_bin_path from ansible.module_utils.common.text.converters import to_bytes from ansible.plugins.connection import ConnectionBase, BUFSIZE from ansible.utils.display import Display @@ -64,10 +64,10 @@ class Connection(ConnectionBase): @staticmethod def _search_executable(executable): - cmd = distutils.spawn.find_executable(executable) - if not cmd: + try: + return get_bin_path(executable) + except ValueError: raise AnsibleError("%s command not found in PATH" % executable) - return cmd def list_zones(self): process = subprocess.Popen([self.zoneadm_cmd, 'list', '-ip'], diff --git a/plugins/lookup/passwordstore.py b/plugins/lookup/passwordstore.py index 7c00f432b1..9abb90e950 100644 --- a/plugins/lookup/passwordstore.py +++ b/plugins/lookup/passwordstore.py @@ -141,9 +141,9 @@ import time import yaml -from distutils import util from ansible.errors import AnsibleError, AnsibleAssertionError from ansible.module_utils.common.text.converters import to_bytes, to_native, to_text +from ansible.module_utils.parsing.convert_bool import boolean from ansible.utils.display import Display from ansible.utils.encrypt import random_password from ansible.plugins.lookup import LookupBase @@ -211,7 +211,7 @@ class LookupModule(LookupBase): try: for key in ['create', 'returnall', 'overwrite', 'backup', 'nosymbols']: if not isinstance(self.paramvals[key], bool): - self.paramvals[key] = util.strtobool(self.paramvals[key]) + self.paramvals[key] = boolean(self.paramvals[key]) except (ValueError, AssertionError) as e: raise AnsibleError(e) if self.paramvals['missing'] not in ['error', 'warn', 'create', 'empty']: