diff --git a/changelogs/fragments/78781-fix-apt-only_upgrade-behavior.yml b/changelogs/fragments/78781-fix-apt-only_upgrade-behavior.yml new file mode 100644 index 00000000000..5b54bf89056 --- /dev/null +++ b/changelogs/fragments/78781-fix-apt-only_upgrade-behavior.yml @@ -0,0 +1,4 @@ +bugfixes: +- >- + apt - Fix module failure when a package is not installed and only_upgrade=True. + Skip that package and check the remaining requested packages for upgrades. (https://github.com/ansible/ansible/issues/78762) diff --git a/lib/ansible/modules/apt.py b/lib/ansible/modules/apt.py index b254fb031e1..08b3e147296 100644 --- a/lib/ansible/modules/apt.py +++ b/lib/ansible/modules/apt.py @@ -711,7 +711,12 @@ def install(m, pkgspec, cache, upgrade=False, default_release=None, package_names.append(name) installed, installed_version, version_installable, has_files = package_status(m, name, version_cmp, version, default_release, cache, state='install') - if (not installed_version and not version_installable) or (not installed and only_upgrade): + if not installed and only_upgrade: + # only_upgrade upgrades packages that are already installed + # since this package is not installed, skip it + continue + + if not installed_version and not version_installable: status = False data = dict(msg="no available installation candidate for %s" % package) return (status, data) diff --git a/test/integration/targets/apt/tasks/repo.yml b/test/integration/targets/apt/tasks/repo.yml index e4e39aa3570..d4cce78a1b0 100644 --- a/test/integration/targets/apt/tasks/repo.yml +++ b/test/integration/targets/apt/tasks/repo.yml @@ -54,7 +54,7 @@ # https://github.com/ansible/ansible/issues/30638 - block: - - name: Fail to install foo=1.0.1 since foo is not installed and only_upgrade is set + - name: Don't install foo=1.0.1 since foo is not installed and only_upgrade is set apt: name: foo=1.0.1 state: present @@ -67,30 +67,36 @@ assert: that: - "apt_result is not changed" - - "apt_result is failed" + - "apt_result is success" - apt: name: foo=1.0.0 allow_unauthenticated: yes - - name: Upgrade foo to 1.0.1 + - name: Upgrade foo to 1.0.1 but don't upgrade foobar since it is not installed apt: - name: foo=1.0.1 + name: foobar=1.0.1,foo=1.0.1 state: present only_upgrade: yes allow_unauthenticated: yes register: apt_result - name: Check install with dpkg - shell: dpkg-query -l foo + shell: "dpkg-query -l {{ item }}" register: dpkg_result + ignore_errors: yes + loop: + - foobar + - foo - name: Check if install was successful assert: that: - "apt_result is success" - - "dpkg_result is success" - - "'1.0.1' in dpkg_result.stdout" + - "dpkg_result.results[0] is failure" + - "'1.0.1' not in dpkg_result.results[0].stdout" + - "dpkg_result.results[1] is success" + - "'1.0.1' in dpkg_result.results[1].stdout" always: - name: Clean up apt: