Ansible dnf 模块 returns 即使 dnf 失败也能成功
Ansible dnf module returns success even when dnf fails
- 这是我系统的初始状态:
- 我安装了 myrpm-2.0。
- 此 rpm 仅创建一个文件。
/usr/share/myfile
作为文件存在。
/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#
- 现在我正在模拟错误情况。我手动删除了该文件并在其位置创建了一个目录。
/root# ls -lrt /usr/share | grep myfile
drwxr-xr-x 2 root root 4096 May 25 18:33 myfile
/root#
- 我准备了一个相同rpm的高版本3.0,复制了相同的文件
/root# rpm -ql /root/update/myrpm-3.0-0.x86_64.rpm
/usr/share
/usr/share/myfile
/root#
4-Test-1:尝试使用 ansible 的内置 dnf 模块进行 rpm 升级。
以下是我的剧本:
/root# cat test.yaml
---
- hosts: localhost
tasks:
- name: update rpm
dnf:
name: "myrpm"
state: latest
/root#
执行此剧本将 return 代码设为 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 为 0。
但是,我可以看到 dnf 命令失败了。
/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:我让我的系统处于与 3 完全相同的状态,并使用直接 dnf 命令而不是 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#
关于为什么 playbook 没有将任务显示为失败的任何线索?
才知道这是ansible高版本修复的bug。
参考 https://github.com/ansible/ansible/issues/77917
- 这是我系统的初始状态:
- 我安装了 myrpm-2.0。
- 此 rpm 仅创建一个文件。
/usr/share/myfile
作为文件存在。
/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#
- 现在我正在模拟错误情况。我手动删除了该文件并在其位置创建了一个目录。
/root# ls -lrt /usr/share | grep myfile
drwxr-xr-x 2 root root 4096 May 25 18:33 myfile
/root#
- 我准备了一个相同rpm的高版本3.0,复制了相同的文件
/root# rpm -ql /root/update/myrpm-3.0-0.x86_64.rpm
/usr/share
/usr/share/myfile
/root#
4-Test-1:尝试使用 ansible 的内置 dnf 模块进行 rpm 升级。 以下是我的剧本:
/root# cat test.yaml
---
- hosts: localhost
tasks:
- name: update rpm
dnf:
name: "myrpm"
state: latest
/root#
执行此剧本将 return 代码设为 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 为 0。 但是,我可以看到 dnf 命令失败了。
/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:我让我的系统处于与 3 完全相同的状态,并使用直接 dnf 命令而不是 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#
关于为什么 playbook 没有将任务显示为失败的任何线索?
才知道这是ansible高版本修复的bug。 参考 https://github.com/ansible/ansible/issues/77917