From 5f94eac41ff040a79d4d00d2f723a9b3a148418e Mon Sep 17 00:00:00 2001 From: Ross Williams Date: Wed, 13 Oct 2021 19:20:45 +0000 Subject: [PATCH] pkgng: fix #3428; install from local file Fixes a bug in which the module reported failure when installing from a local (to the target host) file path. Fixes #3428 --- .../3526-pkgng-add-integration-tests.yml | 1 + plugins/modules/packaging/os/pkgng.py | 24 +++++++++++++++++-- .../targets/pkgng/tasks/freebsd.yml | 22 +++++++++++++++++ 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/changelogs/fragments/3526-pkgng-add-integration-tests.yml b/changelogs/fragments/3526-pkgng-add-integration-tests.yml index 248a27e85e..f56ed6c5ed 100644 --- a/changelogs/fragments/3526-pkgng-add-integration-tests.yml +++ b/changelogs/fragments/3526-pkgng-add-integration-tests.yml @@ -2,3 +2,4 @@ bugfixes: - 'pkgng - ``name=* state=latest`` check for upgrades did not count "Number of packages to be reinstalled" as a `changed` action, giving incorrect results in both regular and check mode (https://github.com/ansible-collections/community.general/pull/3526).' - 'pkgng - an `earlier PR `_ broke check mode so that the module always reports `not changed`. This is now fixed so that the module reports number of upgrade or install actions that would be performed (https://github.com/ansible-collections/community.general/pull/3526).' - 'pkgng - the ``annotation`` functionality was broken and is now fixed, and now also works with check mode (https://github.com/ansible-collections/community.general/pull/3526).' + - 'pkgng - installing a package from a local (to the target host) file reported failure on success `#3428 `_ diff --git a/plugins/modules/packaging/os/pkgng.py b/plugins/modules/packaging/os/pkgng.py index ff7e45fa96..9e14b3931a 100644 --- a/plugins/modules/packaging/os/pkgng.py +++ b/plugins/modules/packaging/os/pkgng.py @@ -140,6 +140,7 @@ EXAMPLES = ''' from collections import defaultdict +import os.path import re from ansible.module_utils.basic import AnsibleModule @@ -154,6 +155,23 @@ def query_package(module, run_pkgng, name): return False +def query_package_name(module, run_pkgng, package): + + # Borrowing this pkg filename detection logic from + # https://github.com/freebsd/pkg/blob/06b59b5/libpkg/pkg_jobs.c#L193-L237 + filename_match = re.search(r'\.(pkg|tzst|t[xbg]z|tar)', package, re.IGNORECASE) + if filename_match is not None and os.path.exists(package): + rc, out, err = run_pkgng('query', '-F', package, '%n') + if rc != 0: + module.fail_json(msg="failed to get name from package file %s: %s" % (package, out), stderr=err) + + package_name = out.strip() + else: + package_name = package + + return package_name + + def query_update(module, run_pkgng, name): # Check to see if a package upgrade is available. @@ -273,10 +291,12 @@ def install_packages(module, run_pkgng, packages, cached, state): # individually verify packages are in requested state for package in package_list: verified = False + package_name = query_package_name(module, run_pkgng, package) + if action == 'install': - verified = query_package(module, run_pkgng, package) + verified = query_package(module, run_pkgng, package_name) elif action == 'upgrade': - verified = not query_update(module, run_pkgng, package) + verified = not query_update(module, run_pkgng, package_name) if verified: action_count[action] += 1 diff --git a/tests/integration/targets/pkgng/tasks/freebsd.yml b/tests/integration/targets/pkgng/tasks/freebsd.yml index f5274d5c5d..66f1272e0e 100644 --- a/tests/integration/targets/pkgng/tasks/freebsd.yml +++ b/tests/integration/targets/pkgng/tasks/freebsd.yml @@ -136,6 +136,28 @@ - pkgng_example4.changed - not pkgng_example4_idempotent.changed +## +## pkgng - example - Install package from local file +- name: Create test package + import_tasks: create-outofdate-pkg.yml + +- name: Install test package from local file + pkgng: + name: '{{ pkgng_test_outofdate_pkg_path }}' + register: pkgng_example_localfile + +- name: Remove test package + pkgng: + name: '{{ pkgng_test_pkg_name }}' + state: absent + register: pkgng_example_localfile_cleanup + +- name: Ensure pkgng installs package from local file + assert: + that: + - pkgng_example_localfile.changed + - pkgng_example_localfile_cleanup.changed + ## ## pkgng - example - Install multiple packages in one command ##