From d9c12d1d53a2b49d2fa67d7a760ab5f0b25ff1a5 Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Tue, 10 Aug 2021 08:08:46 +0200 Subject: [PATCH] Support older version of psutil (RHEL7 and RHEL6) (#2808) (#3188) * Support older version of psutil (RHEL7 and RHEL6) The psutil python module is a true mess, they changed the API twice. The function arguments, as well as the objects that are returned. The documentation does not make it clear which version supports what so the safest implementation is this waterfall approach. A better approach would be to inspect the returned information, rather than trust a version, but that would not be any more efficient. In the end it is better to have something that at least works out-of-the-box on all platforms than something that requires custom updates to system packages before it works as expected. Especially for something as basic as `pids`. * A little bit more concise * Apply suggestions from code review * Add changelog fragment. Co-authored-by: Felix Fontein (cherry picked from commit b5d6457611b88f6b9e6efdc562d39ed427758324) Co-authored-by: Dag Wieers --- .../fragments/2808-pids-older-psutil.yml | 2 ++ plugins/modules/system/pids.py | 19 ++++++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 changelogs/fragments/2808-pids-older-psutil.yml diff --git a/changelogs/fragments/2808-pids-older-psutil.yml b/changelogs/fragments/2808-pids-older-psutil.yml new file mode 100644 index 0000000000..34015e3f2c --- /dev/null +++ b/changelogs/fragments/2808-pids-older-psutil.yml @@ -0,0 +1,2 @@ +bugfixes: +- "pids - avoid crashes for older ``psutil`` versions, like on RHEL6 and RHEL7 (https://github.com/ansible-collections/community.general/pull/2808)." diff --git a/plugins/modules/system/pids.py b/plugins/modules/system/pids.py index 1bee180b08..bfb11ace1a 100644 --- a/plugins/modules/system/pids.py +++ b/plugins/modules/system/pids.py @@ -58,11 +58,20 @@ def compare_lower(a, b): def get_pid(name): pids = [] - for proc in psutil.process_iter(attrs=['name', 'cmdline']): - if compare_lower(proc.info['name'], name) or \ - proc.info['cmdline'] and compare_lower(proc.info['cmdline'][0], name): - pids.append(proc.pid) - + try: + for proc in psutil.process_iter(attrs=['name', 'cmdline']): + if compare_lower(proc.info['name'], name) or \ + proc.info['cmdline'] and compare_lower(proc.info['cmdline'][0], name): + pids.append(proc.pid) + except TypeError: # EL6, EL7: process_iter() takes no arguments (1 given) + for proc in psutil.process_iter(): + try: # EL7 + proc_name, proc_cmdline = proc.name(), proc.cmdline() + except TypeError: # EL6: 'str' object is not callable + proc_name, proc_cmdline = proc.name, proc.cmdline + if compare_lower(proc_name, name) or \ + proc_cmdline and compare_lower(proc_cmdline[0], name): + pids.append(proc.pid) return pids