From c0230342b4973a367e9a301e9b56a2c3e3b8dc45 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Mon, 8 May 2023 19:57:32 +0200 Subject: [PATCH] [PR #6491/9f3c86a5 backport][stable-6] dconf - Try to find a Python interpreter that has gi.repository.GLib (#6504) dconf - Try to find a Python interpreter that has gi.repository.GLib (#6491) * dconf - Try to find a Python interpreter that has gi.repository.GLib If we're invoked in a Python interpreter that doesn't have access to `gi.repository.GLib`, try to find one that does and respawn the task in that interpreter. * ChangeLog fragment for #6491 * Update changelogs/fragments/6491-dconf-respawn.yml Co-authored-by: Felix Fontein * Simplify import code * Get rid of ModuleNotFoundError --------- Co-authored-by: Felix Fontein (cherry picked from commit 9f3c86a589b556d9016b04027aae79e43bc21df4) Co-authored-by: Jonathan Kamens --- changelogs/fragments/6491-dconf-respawn.yml | 2 ++ plugins/modules/dconf.py | 36 +++++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 changelogs/fragments/6491-dconf-respawn.yml diff --git a/changelogs/fragments/6491-dconf-respawn.yml b/changelogs/fragments/6491-dconf-respawn.yml new file mode 100644 index 0000000000..54eec9fa1a --- /dev/null +++ b/changelogs/fragments/6491-dconf-respawn.yml @@ -0,0 +1,2 @@ +minor_changes: + - dconf - if ``gi.repository.GLib`` is missing, try to respawn in a Python interpreter that has it (https://github.com/ansible-collections/community.general/pull/6491). diff --git a/plugins/modules/dconf.py b/plugins/modules/dconf.py index 144440f70b..aefc716005 100644 --- a/plugins/modules/dconf.py +++ b/plugins/modules/dconf.py @@ -143,11 +143,19 @@ EXAMPLES = r""" import os +import sys 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.common.text.converters import to_native from ansible_collections.community.general.plugins.module_utils import deps +glib_module_name = 'gi.repository.GLib' + try: from gi.repository.GLib import Variant, GError except ImportError: @@ -415,6 +423,34 @@ def main(): ], ) + if Variant is None: + # This interpreter can't see the GLib module. To try to fix that, we'll + # look in common locations for system-owned interpreters that can see + # it; if we find one, we'll respawn under it. Otherwise we'll proceed + # with degraded performance, without the ability to parse GVariants. + # Later (in a different PR) we'll actually deprecate this degraded + # performance level and fail with an error if the library can't be + # found. + + if has_respawned(): + # This shouldn't be possible; short-circuit early if it happens. + module.fail_json( + msg="%s must be installed and visible from %s." % + (glib_module_name, sys.executable)) + + interpreters = ['/usr/bin/python3', '/usr/bin/python2', + '/usr/bin/python'] + + interpreter = probe_interpreters_for_module( + interpreters, glib_module_name) + + if interpreter: + # Found the Python bindings; respawn this module under the + # interpreter where we found them. + respawn_module(interpreter) + # This is the end of the line for this process, it will exit here + # once the respawned module has completed. + # Try to be forgiving about the user specifying a boolean as the value, or # more accurately about the fact that YAML and Ansible are quite insistent # about converting strings that look like booleans into booleans. Convert