diff --git a/changelogs/fragments/apt_recommends.yml b/changelogs/fragments/apt_recommends.yml new file mode 100644 index 00000000000..75560b4ba1f --- /dev/null +++ b/changelogs/fragments/apt_recommends.yml @@ -0,0 +1,3 @@ +--- +bugfixes: + - apt - handle comma separated packages from recommends while installing local deb package (https://github.com/ansible/ansible/issues/86609). diff --git a/lib/ansible/modules/apt.py b/lib/ansible/modules/apt.py index ec3668b2ebf..a62039723c1 100644 --- a/lib/ansible/modules/apt.py +++ b/lib/ansible/modules/apt.py @@ -854,6 +854,33 @@ def get_field_of_deb(m, deb_file, field="Version"): return to_native(stdout).strip('\n') +def install_recommended_packages(cache: apt.Cache, recommended_packages: str) -> list[str]: + deps_to_install = [] + for recommend_one_of in apt_pkg.parse_depends(recommended_packages, False): + for name, version, op in recommend_one_of: + try: + pkg = cache[name] + except KeyError: + # no package found, continue with next recommended package + continue + + if pkg.is_installed and version and op and apt_pkg.check_dep(pkg.installed.version, op, version): + # package is installed and the version is the same, continue with next recommended package + break + + if not pkg.candidate: + # no candidate found, continue with next recommended package + continue + + if version and op and not apt_pkg.check_dep(pkg.candidate.version, op, version): + # candidate version does not match the version, continue with next recommended package + continue + + deps_to_install.append(name) + break + return deps_to_install + + def install_deb( m, debs, cache, force, fail_on_autoremove, install_recommends, allow_unauthenticated, @@ -901,7 +928,7 @@ def install_deb( # Install 'Recommends' of this deb file if install_recommends: pkg_recommends = get_field_of_deb(m, deb_file, "Recommends") - deps_to_install.extend([pkg_name.strip() for pkg_name in pkg_recommends.split()]) + deps_to_install.extend(install_recommended_packages(cache, pkg_recommends)) # and add this deb to the list of packages to install pkgs_to_install.append(deb_file) diff --git a/test/integration/targets/apt/tasks/url-with-deps.yml b/test/integration/targets/apt/tasks/url-with-deps.yml index 7e628c95b75..3262c9bdf63 100644 --- a/test/integration/targets/apt/tasks/url-with-deps.yml +++ b/test/integration/targets/apt/tasks/url-with-deps.yml @@ -55,15 +55,20 @@ register: apt_url_deps - name: check to make sure we installed the package - shell: dpkg -l | grep baz + shell: dpkg-query -l baz failed_when: False register: baz_dpkg_result - - name: check to make sure we installed the package's recommends - shell: dpkg -l | grep rolldice + - name: check to make sure we installed the package's recommends (rolldice) + shell: dpkg-query -l rolldice failed_when: False register: rolldice_dpkg_result + - name: check to make sure we installed the package's recommends (uidmap) + shell: dpkg-query -l uidmap + failed_when: False + register: uidmap_dpkg_result + - name: verify real installation of bar assert: that: @@ -72,6 +77,8 @@ - baz_dpkg_result.rc == 0 - rolldice_dpkg_result is successful - rolldice_dpkg_result.rc == 0 + - uidmap_dpkg_result is successful + - uidmap_dpkg_result.rc == 0 always: - name: uninstall packages with apt @@ -80,5 +87,6 @@ - echo-hello - rolldice - baz + - uidmap state: absent purge: yes diff --git a/test/integration/targets/setup_deb_repo/files/package_specs/stable/baz-1.0.0 b/test/integration/targets/setup_deb_repo/files/package_specs/stable/baz-1.0.0 index 1e5d0a4a1fd..905ceafe9c3 100644 --- a/test/integration/targets/setup_deb_repo/files/package_specs/stable/baz-1.0.0 +++ b/test/integration/targets/setup_deb_repo/files/package_specs/stable/baz-1.0.0 @@ -8,4 +8,4 @@ Section: system Maintainer: John Doe Architecture: all Description: Dummy package -Recommends: rolldice +Recommends: rolldice, uidmap