summaryrefslogtreecommitdiff
path: root/lib/ansible/modules/dnf.py
diff options
context:
space:
mode:
authorMatt Davis <nitzmahone@users.noreply.github.com>2021-02-10 21:32:59 -0800
committerGitHub <noreply@github.com>2021-02-10 21:32:59 -0800
commit4c5ce5a1a9e79a845aff4978cfeb72a0d4ecf7d6 (patch)
treea1511f836f61f9f662d5b3a3c0231c9a02aa7eeb /lib/ansible/modules/dnf.py
parent8a175f59c939ca29ad56f3fa9edbc37a8656879a (diff)
downloadansible-4c5ce5a1a9e79a845aff4978cfeb72a0d4ecf7d6.tar.gz
module compat for py3.8+ controller (#73423)
* module compat for py3.8+ controller * replaced internal usages of selinux bindings with internal ctypes binding (allows basic selinux operations from any Python interpreter), plus tests * added new respawn_module API to allow modules to import Python packages that are only available under a well-known interpreter, plus tests * added respawn logic to modules that need Python libs from a specific system interpreter (apt, apt_repository, dnf, yum) minimize internal HAVE_SELINUX usage spurious junk pep8 * pylint fixes * add RHEL8 Python 3.8 testing * more pylint * import sanity * unit tests * changelog update * fix a bunch of stuff * tweak changelog * fix setup_rpm_repo on EL8 * misc sanity/test fixes * misc feedback tweaks * fix import fallback in test module * fix selinux MU test * fix dnf tests to avoid python-dependent test packages * add trailing LFs to aliases * fix yum tests to avoid test package with Python deps * hack create_repo for EL6 to create noarch package
Diffstat (limited to 'lib/ansible/modules/dnf.py')
-rw-r--r--lib/ansible/modules/dnf.py76
1 files changed, 34 insertions, 42 deletions
diff --git a/lib/ansible/modules/dnf.py b/lib/ansible/modules/dnf.py
index 7550b3371f..b3a73fc1a4 100644
--- a/lib/ansible/modules/dnf.py
+++ b/lib/ansible/modules/dnf.py
@@ -324,6 +324,15 @@ import os
import re
import sys
+from ansible.module_utils._text import to_native, to_text
+from ansible.module_utils.urls import fetch_file
+from ansible.module_utils.six import PY2, text_type
+from distutils.version import LooseVersion
+
+from ansible.module_utils.basic import AnsibleModule
+from ansible.module_utils.common.respawn import has_respawned, probe_interpreters_for_module, respawn_module
+from ansible.module_utils.yumdnf import YumDnf, yumdnf_argument_spec
+
try:
import dnf
import dnf.cli
@@ -335,14 +344,6 @@ try:
except ImportError:
HAS_DNF = False
-from ansible.module_utils._text import to_native, to_text
-from ansible.module_utils.urls import fetch_file
-from ansible.module_utils.six import PY2, text_type
-from distutils.version import LooseVersion
-
-from ansible.module_utils.basic import AnsibleModule
-from ansible.module_utils.yumdnf import YumDnf, yumdnf_argument_spec
-
class DnfModule(YumDnf):
"""
@@ -509,40 +510,31 @@ class DnfModule(YumDnf):
return rc
def _ensure_dnf(self):
- if not HAS_DNF:
- if PY2:
- package = 'python2-dnf'
- else:
- package = 'python3-dnf'
-
- if self.module.check_mode:
- self.module.fail_json(
- msg="`{0}` is not installed, but it is required"
- "for the Ansible dnf module.".format(package),
- results=[],
- )
-
- rc, stdout, stderr = self.module.run_command(['dnf', 'install', '-y', package])
- global dnf
- try:
- import dnf
- import dnf.cli
- import dnf.const
- import dnf.exceptions
- import dnf.subject
- import dnf.util
- except ImportError:
- self.module.fail_json(
- msg="Could not import the dnf python module using {0} ({1}). "
- "Please install `{2}` package or ensure you have specified the "
- "correct ansible_python_interpreter.".format(sys.executable, sys.version.replace('\n', ''),
- package),
- results=[],
- cmd='dnf install -y {0}'.format(package),
- rc=rc,
- stdout=stdout,
- stderr=stderr,
- )
+ if HAS_DNF:
+ return
+
+ system_interpreters = ['/usr/libexec/platform-python',
+ '/usr/bin/python3',
+ '/usr/bin/python2',
+ '/usr/bin/python']
+
+ if not has_respawned():
+ # probe well-known system Python locations for accessible bindings, favoring py3
+ interpreter = probe_interpreters_for_module(system_interpreters, 'dnf')
+
+ if interpreter:
+ # respawn under the interpreter where the bindings should be found
+ respawn_module(interpreter)
+ # end of the line for this module, the process will exit here once the respawned module completes
+
+ # done all we can do, something is just broken (auto-install isn't useful anymore with respawn, so it was removed)
+ self.module.fail_json(
+ msg="Could not import the dnf python module using {0} ({1}). "
+ "Please install `python3-dnf` or `python2-dnf` package or ensure you have specified the "
+ "correct ansible_python_interpreter. (attempted {2})"
+ .format(sys.executable, sys.version.replace('\n', ''), system_interpreters),
+ results=[]
+ )
def _configure_base(self, base, conf_file, disable_gpg_check, installroot='/'):
"""Configure the dnf Base object."""