From 38e0d97c8bec6fc51abd348f6a09c5e359aa0faf Mon Sep 17 00:00:00 2001 From: Elie Moreau Date: Sat, 30 Oct 2021 17:17:45 +1100 Subject: [PATCH] [Pacman Module] Allow for the pacman repository check to be skipped when it's not needed (#3606) * Allow for the pacman repository check to be skipped when it's not needed * Adding a changelog fragment * Undo the variable rename because the lint doesn't like it * Update changelogs/fragments/3606-pacman-speed-up-check-if-package-is-installed.yml Co-authored-by: Felix Fontein Co-authored-by: Elie Moreau Co-authored-by: Felix Fontein --- ...speed-up-check-if-package-is-installed.yml | 2 + plugins/modules/packaging/os/pacman.py | 57 ++++++++++--------- 2 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 changelogs/fragments/3606-pacman-speed-up-check-if-package-is-installed.yml diff --git a/changelogs/fragments/3606-pacman-speed-up-check-if-package-is-installed.yml b/changelogs/fragments/3606-pacman-speed-up-check-if-package-is-installed.yml new file mode 100644 index 0000000000..12197516af --- /dev/null +++ b/changelogs/fragments/3606-pacman-speed-up-check-if-package-is-installed.yml @@ -0,0 +1,2 @@ +minor_changes: +- "pacman - speed up checking if the package is installed, when the latest version check is not needed (https://github.com/ansible-collections/community.general/pull/3606)." diff --git a/plugins/modules/packaging/os/pacman.py b/plugins/modules/packaging/os/pacman.py index ea138fa614..c85faf208c 100644 --- a/plugins/modules/packaging/os/pacman.py +++ b/plugins/modules/packaging/os/pacman.py @@ -189,38 +189,43 @@ def get_name(module, pacman_output): module.fail_json(msg="get_name: fail to retrieve package name from pacman output") -def query_package(module, pacman_path, name, state="present"): +def query_package(module, pacman_path, name, state): """Query the package status in both the local system and the repository. Returns a boolean to indicate if the package is installed, a second boolean to indicate if the package is up-to-date and a third boolean to indicate whether online information were available """ - if state == "present": - lcmd = "%s --query %s" % (pacman_path, name) - lrc, lstdout, lstderr = module.run_command(lcmd, check_rc=False) - if lrc != 0: - # package is not installed locally + + lcmd = "%s --query %s" % (pacman_path, name) + lrc, lstdout, lstderr = module.run_command(lcmd, check_rc=False) + if lrc != 0: + # package is not installed locally + return False, False, False + else: + # 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 installed_name != name: return False, False, False - else: - # 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 installed_name != name: - return False, False, False - # get the version installed locally (if any) - lversion = get_version(lstdout) + # no need to check the repository if state is present or absent + # return False for package version check, because we didn't check it + if state == 'present' or state == 'absent': + return True, False, False - rcmd = "%s --sync --print-format \"%%n %%v\" %s" % (pacman_path, name) - rrc, rstdout, rstderr = module.run_command(rcmd, check_rc=False) - # get the version in the repository - rversion = get_version(rstdout) + # get the version installed locally (if any) + lversion = get_version(lstdout) - if rrc == 0: - # Return True to indicate that the package is installed locally, and the result of the version number comparison - # to determine if the package is up-to-date. - return True, (lversion == rversion), False + rcmd = "%s --sync --print-format \"%%n %%v\" %s" % (pacman_path, name) + rrc, rstdout, rstderr = module.run_command(rcmd, check_rc=False) + # get the version in the repository + rversion = get_version(rstdout) + + if rrc == 0: + # Return True to indicate that the package is installed locally, and the result of the version number comparison + # to determine if the package is up-to-date. + return True, (lversion == rversion), False # package is installed but cannot fetch remote Version. Last True stands for the error - return True, True, True + return True, True, True def update_package_db(module, pacman_path): @@ -291,7 +296,7 @@ def remove_packages(module, pacman_path, packages): # Using a for loop in case of error, we can report the package that failed for package in packages: # Query the package first, to see if we even need to remove - installed, updated, unknown = query_package(module, pacman_path, package) + installed, updated, unknown = query_package(module, pacman_path, package, 'absent') if not installed: continue @@ -330,7 +335,7 @@ def install_packages(module, pacman_path, state, packages, package_files): to_install_files = [] for i, package in enumerate(packages): # if the package is installed and state == present or state == latest and is up-to-date then skip - installed, updated, latestError = query_package(module, pacman_path, package) + installed, updated, latestError = query_package(module, pacman_path, package, state) if latestError and state == 'latest': package_err.append(package) @@ -399,7 +404,7 @@ def check_packages(module, pacman_path, packages, state): } for package in packages: - installed, updated, unknown = query_package(module, pacman_path, package) + installed, updated, unknown = query_package(module, pacman_path, package, state) if ((state in ["present", "latest"] and not installed) or (state == "absent" and installed) or (state == "latest" and not updated)):