From cd0e038b746f426003ba7177f5ff4882db9dfe9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20Deparis?= Date: Mon, 23 Dec 2019 04:41:39 +0100 Subject: [PATCH] Don't rely anymore on locale-dependent wording in Pacman output (#65878) Use line position instead, as specified in upstream pacman source code. See: https://git.archlinux.org/pacman.git/tree/src/pacman/package.c#n260 Fixes: https://github.com/ansible/ansible/issues/64682 Fixes: https://github.com/ansible/ansible/issues/65237 --- lib/ansible/modules/packaging/os/pacman.py | 42 ++++++++++++++++------ 1 file changed, 31 insertions(+), 11 deletions(-) diff --git a/lib/ansible/modules/packaging/os/pacman.py b/lib/ansible/modules/packaging/os/pacman.py index 1672598bd0..2ab3ab7f97 100644 --- a/lib/ansible/modules/packaging/os/pacman.py +++ b/lib/ansible/modules/packaging/os/pacman.py @@ -158,22 +158,38 @@ import re from ansible.module_utils.basic import AnsibleModule -def get_version(pacman_output): +def get_version(pacman_output, from_sync=False): """Take pacman -Qi or pacman -Si output and get the Version""" lines = pacman_output.split('\n') - for line in lines: - if line.startswith('Version '): - return line.split(':')[1].strip() - return None + # Version information is always printed out on the 2nd line of a + # query output (-Q/--query) and on the 3rd line of a sync output + # (-S/--sync). Obviously lines index begin at 0. + # See: https://git.archlinux.org/pacman.git/tree/src/pacman/package.c#n260 + index = 1 + if from_sync: + index = 2 + try: + version = lines[index].split(':')[1].strip() + except IndexError: + version = None + return version -def get_name(module, pacman_output): +def get_name(module, pacman_output, from_sync=False): """Take pacman -Qi or pacman -Si output and get the package name""" lines = pacman_output.split('\n') - for line in lines: - if line.startswith('Name '): - return line.split(':')[1].strip() - module.fail_json(msg="get_name: fail to retrieve package name from pacman output") + # Package name is always printed out on the 1st line of a + # query output (-Q/--query) and on the 2nd line of a sync output + # (-S/--sync). Obviously lines index begin at 0. + # See: https://git.archlinux.org/pacman.git/tree/src/pacman/package.c#n260 + index = 0 + if from_sync: + index = 1 + try: + name = lines[index].split(':')[1].strip() + except IndexError: + module.fail_json(msg="get_name: fail to retrieve package name from pacman output") + return name def query_package(module, pacman_path, name, state="present"): @@ -190,6 +206,10 @@ def query_package(module, pacman_path, name, state="present"): # a non-zero exit code doesn't always mean the package is installed # for example, if the package name queried is "provided" by another package installed_name = get_name(module, lstdout) + # If something goes weird and the first line of the output + # does not contain a name, but an error message for exemple, + # it's not that serious, because the following test will + # exit us sooner. if installed_name != name: return False, False, False @@ -199,7 +219,7 @@ def query_package(module, pacman_path, name, state="present"): rcmd = "%s --sync --info %s" % (pacman_path, name) rrc, rstdout, rstderr = module.run_command(rcmd, check_rc=False) # get the version in the repository - rversion = get_version(rstdout) + rversion = get_version(rstdout, True) if rrc == 0: # Return True to indicate that the package is installed locally, and the result of the version number comparison