linuxansiblerpmdnf

Ansible dnf module returns success even when dnf fails


  1. This is the initial state of my system:
    /root# rpm -q myrpm
    myrpm-2.0-0.x86_64
    /root# rpm -ql myrpm-2.0-0.x86_64
    /usr/share
    /usr/share/myfile
    /root# ls -lrt /usr/share | grep myfile
    -rw-r--r--   1 root root     11 May 25 17:32 myfile
    /root#
  1. Now I am simulating an error condition. I manually removed the file and created a directory in it's place.
    /root# ls -lrt /usr/share | grep myfile
    drwxr-xr-x   2 root root   4096 May 25 18:33 myfile
    /root#
  1. I prepared a higher version 3.0 of the same rpm, which copies the same file.
    /root# rpm -ql /root/update/myrpm-3.0-0.x86_64.rpm
    /usr/share
    /usr/share/myfile
    /root#

4-Test-1: Trying rpm upgrade using ansible's builtin dnf module. Following is my playbook:

/root# cat test.yaml
---
- hosts: localhost
  tasks:
    - name: update rpm
      dnf:
        name: "myrpm"
        state: latest
/root#

Executing this playbook gives return code as 0.

/root# ansible-playbook -vvv test.yaml
...
changed: [localhost] => {
    "changed": true,
    "invocation": {
        "module_args": {
            "allow_downgrade": false,
            "autoremove": false,
            "bugfix": false,
            "conf_file": null,
            "disable_excludes": null,
            "disable_gpg_check": false,
            "disable_plugin": [],
            "disablerepo": [],
            "download_dir": null,
            "download_only": false,
            "enable_plugin": [],
            "enablerepo": [],
            "exclude": [],
            "install_repoquery": true,
            "install_weak_deps": true,
            "installroot": "/",
            "list": null,
            "lock_timeout": 30,
            "name": [
                "myrpm"
            ],
            "releasever": null,
            "security": false,
            "skip_broken": false,
            "state": "latest",
            "update_cache": false,
            "update_only": false,
            "validate_certs": true
        }
    },
    "msg": "",
    "rc": 0,
    "results": [
        "Installed: myrpm-3.0-0.x86_64",
        "Removed: myrpm-2.0-0.x86_64"
    ]
}
META: ran handlers
META: ran handlers

PLAY RECAP *******************************************************************************************
localhost                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

/root# echo $?
0
/root#

rc is 0 as per the verbose log. However, I can see that dnf command has failed.

/root# dnf history | head -n 3
ID     | Command line             | Date and time    | Action(s)      | Altered
-------------------------------------------------------------------------------
    27 |                          | 2022-05-25 18:39 | Upgrade        |    1 EE
/root# dnf history info 27 | tail -6
Packages Altered:
 ** Upgrade  myrpm-3.0-0.x86_64 @My_Update
    Upgraded myrpm-2.0-0.x86_64 @@System
Scriptlet output:
   1 error: unpacking of archive failed on file /usr/share/myfile: cpio: File from package already exists as a directory in system
   2 error: myrpm-3.0-0.x86_64: install failed
/root#

4-Test-2: I made my system in exact same state as 3, and used direct dnf command instead of playbook.

/root# dnf update myrpm
...
  Preparing        :                                                                              1/1
  Upgrading        : myrpm-3.0-0.x86_64                                                           1/2
Error unpacking rpm package myrpm-3.0-0.x86_64
error: unpacking of archive failed on file /usr/share/myfile: cpio: File from package already exists as a directory in system

  Cleanup          : myrpm-2.0-0.x86_64                                                           2/2
error: myrpm-3.0-0.x86_64: install failed

  Verifying        : myrpm-3.0-0.x86_64                                                           1/2
  Verifying        : myrpm-2.0-0.x86_64                                                           2/2

Failed:
  myrpm-3.0-0.x86_64

Error: Transaction failed
/root# echo $?
1
/root# 

Any clue on why the playbook did not show task as failed?


Solution

  • Got to know that this is a bug fixed in higher versions of ansible. Refer https://github.com/ansible/ansible/issues/77917