Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zypper fails to install with specified version #4371

Closed
1 task done
tover99 opened this issue Mar 16, 2022 · 4 comments
Closed
1 task done

zypper fails to install with specified version #4371

tover99 opened this issue Mar 16, 2022 · 4 comments
Labels
bug This issue/PR relates to a bug module module os packaging plugins plugin (any type)

Comments

@tover99
Copy link
Contributor

tover99 commented Mar 16, 2022

Summary

If a package is already installed on the target system, the zypper module fails to install a specified different version, claiming it's already there.

Issue Type

Bug Report

Component Name

zypper

Ansible Version

$ ansible --version
ansible [core 2.12.2]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python3.8/site-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/bin/ansible
  python version = 3.8.10 (default, May  6 2021, 00:05:59) [GCC 10.2.1 20201203]
  jinja version = 3.0.3
  libyaml = True

Community.general Version

$ ansible-galaxy collection list community.general

# /usr/lib/python3.8/site-packages/ansible_collections
Collection        Version
----------------- -------
community.general 4.4.0

Configuration

$ ansible-config dump --only-changed

OS / Environment

# cat /etc/os-release
NAME="SLES"
VERSION="15-SP2"
VERSION_ID="15.2"
PRETTY_NAME="SUSE Linux Enterprise Server 15 SP2"
ID="sles"
ID_LIKE="suse"
ANSI_COLOR="0;32"
CPE_NAME="cpe:/o:suse:sles:15:sp2"

Steps to Reproduce

The following task ALWAYS reports [ok] if any version of a-very-important-package is already installed on the target system.

    - name: Install a specific package version via zypper
      zypper:
        name:
          - "a-very-important-package=2.1"
        state: present
        oldpackage : yes

As soon as at least one other package WITHOUT a version specification is requestet, everything works as expected.

    - name: Install a specific package version via zypper
      zypper:
        name:
          - "a-very-important-package=2.1"
          - "another-package"
        state: present
        oldpackage : yes

Expected Results

specific package version gets installed/updated/downgraded

Actual Results

specific package version is reported as present even if it is not in the requested version

Code of Conduct

  • I agree to follow the Ansible Code of Conduct
@ansibullbot
Copy link
Collaborator

Files identified in the description:

If these files are incorrect, please update the component name section of the description or use the !component bot command.

click here for bot help

@ansibullbot
Copy link
Collaborator

@ansibullbot ansibullbot added bug This issue/PR relates to a bug module module os packaging plugins plugin (any type) labels Mar 16, 2022
@tover99
Copy link
Contributor Author

tover99 commented Mar 16, 2022

The problem seems to be rooted in the method package_present(m, name, want_latest):

. . .
def package_present(m, name, want_latest):
    "install and update (if want_latest) the packages in name_install, while removing the packages in name_remove"
    retvals = {'rc': 0, 'stdout': '', 'stderr': ''}
    packages, urls = get_want_state(name)

    # add oldpackage flag when a version is given to allow downgrades
    if any(p.version for p in packages):
        m.params['oldpackage'] = True

    if not want_latest:
        # for state=present: filter out already installed packages
        # if a version is given leave the package in to let zypper handle the version
        # resolution
        packageswithoutversion = [p for p in packages if not p.version]
        prerun_state = get_installed_state(m, packageswithoutversion)
        # generate lists of packages to install or remove
        packages = [p for p in packages if p.shouldinstall != (p.name in prerun_state)]
. . .

If no packages without version are requested packageswithoutversion will be empty. But the method get_installed_state() returns the state of ALL installed packages, when called with an empty package list. This, I believe, results in an exessive filter list prerun_state which essentially removes all packages that are installed in any version on the target system from the request list. This completely blocks the update/downgrade path of any installed package (unless you always specify one aditional "dummy" package as a workaround)

Something like this would fix the problem:

. . .
       prerun_state = {}
       if packageswithoutversion:
           prerun_state = get_installed_state(m, packageswithoutversion)
. . .

Of course one could also change the behaviour of get_installed_state() when called with an empty packagelist.

My appologies, if I got this totaly wrong. I don't speak python really ;-).

@felixfontein
Copy link
Collaborator

Fixed in #4421.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue/PR relates to a bug module module os packaging plugins plugin (any type)
Projects
None yet
Development

No branches or pull requests

3 participants