'Best way to check for installed yum package/rpm version in Ansible and use it
I've been getting my feet wet with Ansible (2.0.0.2) on CentOS 7. I'm trying to obtain a version from an installed rpm/yum package, but ran into a warning message when running the script.
Ansible script:
---
- name: Get version of RPM
shell: yum list installed custom-rpm | grep custom-rpm | awk '{print $2}' | cut -d'-' -f1
register: version
changed_when: False
- name: Update some file with version
lineinfile:
dest: /opt/version.xml
regexp: "<version>"
line: " <version>{{ version.stdout }}</version>"
Running this works fine and does what it's supposed to, but it's returning a warning after it executes:
ok: [default] => {"changed": false, "cmd": "yum list installed custom-rpm | grep custom-rpm | awk '{print $2}' | cut -d'-' -f1", "delta": "0:00:00.255406", "end": "2016-05-17 23:11:54.998838", "rc": 0, "start": "2016-05-17 23:11:54.743432", "stderr": "", "stdout": "3.10.2", "stdout_lines": ["3.10.2"], "warnings": ["Consider using yum module rather than running yum"]}
[WARNING]: Consider using yum module rather than running yum
I looked up information for the yum module on the Ansible site, but I don't really want to install/update/delete anything.
I could simply ignore it or suppress it, but I was curious if there was a better way?
Solution 1:[1]
The way you do it is perfectly fine. The check which is causing the warning is very simply and just checks the first word against a pre-defined list. It ignores further options and often results in warnings which can not be solved with the corresponding module, like in the yum
case.
To get rid of the warning you can simply do a which
:
shell: `which yum` list installed custom-rpm | grep custom-rpm | awk '{print $2}' | cut -d'-' -f1
which
looks up the the complete path of yum
, which then is executed. It's the exact same thing, but from viewpoint of Ansible it calls which
, not yum
which avoids the warning.
If you want to deactivate this kind of warnings globally you can set command_warnings = False
in your ansible.cfg
. (See docs)
According to the docs you can also add warn=no
at the end of your command but this really looks strange to me as it appears to be part of the command.
Solution 2:[2]
I just want to update this old discussion to point out that there is now a package module that makes this more straightforward
- name: get the rpm or apt package facts
package_facts:
manager: "auto"
- name: show apache2 version
debug: var=ansible_facts.packages.apache2[0].version
Solution 3:[3]
I think more native ansible way would be:
- name: get package version
yum:
list: package_name
register: package_name_version
- name: set package version
set_fact:
package_name_version: "{{ package_name_version.results|selectattr('yumstate','equalto','installed')|map(attribute='version')|list|first }}"
Solution 4:[4]
How about you use RPM to retrieve the version directly in stead of going trough various pipes:
rpm -q --qf "%{VERSION}" custom-rpm
Solution 5:[5]
It's okay to suppress this warning in your case. Use args
like:
---
- name: Get version of RPM
shell: yum list installed custom-rpm | grep custom-rpm | awk '{print $2}' | cut -d'-' -f1
register: version
changed_when: False
args:
warn: no
Equivalent to warn=no
on the shell:
line but tidier.
Solution 6:[6]
I didn't like any of these answers.
- name: use command to pull version
command: '/usr/bin/rpm -qa custom-rpm --queryformat %{VERSION}'
register: version
ignore_warnings: True
changed_when: False
Solution 7:[7]
use the YUM module as suggested. This really helps. You need not do any installation/update/delete. More over this gives you more options like if the package is already installed it would just ignore it.
Solution 8:[8]
Varaint of peaxol answer setting a fact with the installed package version number for futher tests
- name: Find if custom_rpm is installed
yum:
list: custom_rpm
register: custom_rpm_yum_packages
when: ansible_os_family == "RedHat"
- name: Extract custom_rpm actual installed version
set_fact:
actual_custom_rpm_version: "{{custom_rpm_yum_packages|json_query(jsonquery)}}"
vars:
jsonquery: "results[?yumstate=='installed'].version"
when: ansible_os_family == "RedHat"
- debug:
var: actual_custom_rpm_version
Solution 9:[9]
As mentioned by others, you can use the shell command. I found this answer useful for using the ansible yum module instead of the shell command as recommended by the ansible warning: How can I get the installed YUM packages with Ansible?
Summarizing it here for easy reference: You can use yum list from the native yum module in ansible.
- hosts: localhost
tasks:
- name: Get installed packages
sudo: yes
yum: list=installed
register: yum_packages
changed_when: False
To view the contents of yum_packages:
- debug:
var: yum_packages
yum_packages contains a list of all installed packages.
You can then get the version of package of interest by:
- debug: var=item
with_items: "{{yum_packages|json_query(jsonquery)}}"
vars:
jsonquery: "results[?name=='tar'].version"
Please note that jsonquery is only available from ansible 2.2 onwards.
Solution 10:[10]
Try adding the ignore_errors
option to handle this. See the Error Handing page for details and examples
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow