Search code examples
ansiblesusesleszypper

Ansible on SLES: zypper plugin not able to install PostgreSQL 14


I am trying my hand on Ansible after having a very nice training in it. Currently, my task is to create a playbook that sets up a PostgreSQL cluster (with Patroni and etcd).

However, while installing PostgreSQL should be a pretty easy task, doing it using the zypper plugin throws an error. First, the part of the playbook that should install PostgreSQL:

- name: Installation PostgreSQL 14 Latest ohne Recommendations
  become: true
  zypper:
    disable_recommends: true
    name:
      postgresql14-server
      postgresql14-contrib
      postgresql14-devel
    update_cache: true
  when: ansible_host in pgservers

The error message given is this:

fatal: [goeccdb22l]: FAILED! => {"changed": false, "cmd": ["/usr/bin/zypper", "--quiet", "--non-interactive", "--xmlout", "install", "--type", "package", "--auto-agree-with-licenses", "--no-recommends", "--", "+postgresql14-server postgresql14-contrib postgresql14-devel"], "msg": "No provider of '+postgresql14-server postgresql14-contrib postgresql14-devel' found.", "rc": 104, "stderr": "", "stderr_lines": [], "stdout": "<?xml version='1.0'?>\n<stream>\n<message type=\"error\">No provider of &apos;+postgresql14-server postgresql14-contrib postgresql14-devel&apos; found.</message>\n</stream>\n", "stdout_lines": ["<?xml version='1.0'?>", "<stream>", "<message type=\"error\">No provider of &apos;+postgresql14-server postgresql14-contrib postgresql14-devel&apos; found.</message>", "</stream>"]}

Let's extract the error message:

"msg": "No provider of '+postgresql14-server postgresql14-contrib postgresql14-devel' found."

I tried to replicate the problem using the shell on the target server. However, running the command seems to be able to install the packages:

ansible@goeccdb22l:~> sudo /usr/bin/zypper install --type package --auto-agree-with-licenses --no-recommends -- +postgresql14-server postgresql14-contrib postgresql14-devel
Loading repository data...
Reading installed packages...
Resolving package dependencies...

The following 12 NEW packages are going to be installed:
  libecpg6 libopenssl-1_1-devel libpq5 postgresql postgresql14 postgresql14-contrib postgresql14-devel postgresql14-server postgresql-contrib postgresql-devel postgresql-server zlib-devel

The following package needs additional customer contract to get support:
  postgresql14

12 new packages to install.
Overall download size: 8.0 MiB. Already cached: 0 B. After the operation, additional 35.4 MiB will be used.
Continue? [y/n/v/...? shows all options] (y):

I've removed only the --quiet and --non-interactive options from the command, but kept all other given options.

The best idea I have is that the user/privilege escalation workings could be different from me logging in as the Ansible user to the target and just using sudo before the command.

Edit 1: I have developed an idea what the problem could be. As I mentioned above, when I tested the command, I removed two options: --quiet and --non-interactive. Testing the command with those two options gives the message:

The flag --quiet is not known.

However, using man zypper, I can clearly see that --quiet is a documented option:

   -q, --quiet
       Suppress normal output. Brief (esp. result notification) messages and error messages will still be printed, though. If used together with conflicting --verbose option, the --verbose option takes preference.

Now, my idea is that Ansible calls the command it documents in the return XML, but that because somehow --quiet is not understood it interprets that as nothing providing the requested package list. So that would leave two questions:

  • Why is --quiet not understood, yet documented? Is that a problem of SLES vs. OpenSuse?
  • How to work around that?

As the Ansible zypper module has no option to suppress the --quiet option I don't see any chance of working around it with parameters. The last option would be to split the zypper task into smaller shell tasks which I would like to avoid if possible.


Solution

  • So, with the help of a knowledgeable sysadmin I was able to diagnose the problem.

    The list of packages documented above was not in fact a list. As I missed the dashes in front of the packages, Ansible accepted the packages with the newlines and everything as one package name and tried to install it.

    The solution is to change the packages into a list of packages by prefixing them with dashes/minus signs.

    The problem with --quiet was that it is a positional argument, and I used the wrong position when testing it.