如何使用Ansible获取软件包的最新可用版本
问题描述
我想通过Ansible的yum模块实现yum check-update package_name命令的功能——这个命令可以查看执行yum update后指定软件包会更新到的版本。示例如下:
root@host: $ yum check-update kernel [...] kernel.x86_64 3.10.0-1160.80.1.el7 [...] root@host: $
我尝试过以下配置:
- name: 查看所有可更新包 ansible.builtin.yum: list: updates update_cache: true
但这个配置无法限定到单个软件包或匹配模式(比如java*)。
目前我用了一个不够优雅且效率低下的临时方案(因为需要下载包):
- name: 检查xyz的最新可用版本 yum: name: xyz state: latest download_only: true become: true register: _result - name: 提取xyz版本号 set_fact: latestXyz: "{{ _result.changes.updated[0][1] | regex_search('xyz-(.+).x86_64.*', '\\1') }}"
请问有没有更优的实现方式?
更优实现方案
方案1:直接调用yum check-update命令解析输出
这是最贴近原生命令效果的方案,无需下载包,效率更高:
- name: 检查指定包的可更新版本 ansible.builtin.command: yum check-update {{ package_name }} args: warn: false # 避免Ansible提示优先使用yum模块 become: true register: yum_check_result changed_when: false # 该操作不会修改系统状态 failed_when: yum_check_result.rc not in [0, 100] # 返回码100表示有可更新包,0表示无更新 - name: 提取并注册最新版本号 set_fact: latest_package_version: "{{ yum_check_result.stdout | regex_search('^' ~ package_name ~ '\\.[a-z0-9_]+\\s+(\\S+)', '\\1') | first }}" when: yum_check_result.rc == 100
- 说明:
yum check-update的返回码规则为:0=无可用更新,100=存在可更新包,其他值为执行错误;正则匹配支持java*这类通配符,只要原生命令能匹配到目标包。
方案2:yum模块结合Jinja2过滤结果
如果倾向于使用Ansible原生模块而非直接调用命令,可先获取所有可更新包,再过滤目标包:
- name: 获取所有可更新包列表 ansible.builtin.yum: list: updates update_cache: true become: true register: all_updates - name: 提取指定包的最新版本 set_fact: latest_package_version: "{{ all_updates.results | selectattr('name', 'match', '^' ~ package_name ~ '$') | map(attribute='version') | first }}" when: all_updates.results | selectattr('name', 'match', '^' ~ package_name ~ '$') | list | length > 0
- 说明:若要支持
java*这类通配符,将match改为search,正则调整为^java即可;该方案无需下载包,比临时方案更高效,同时保留模块使用的规范性。
方案3:使用repoquery工具(RHEL/CentOS专属)
如果系统已安装yum-utils包,可直接用repoquery从仓库查询最新版本:
- name: 确保yum-utils已安装 ansible.builtin.yum: name: yum-utils state: present become: true - name: 查询指定包的最新可用版本 ansible.builtin.command: repoquery --latest {{ package_name }} become: true register: repoquery_result changed_when: false - name: 注册版本号 set_fact: latest_package_version: "{{ repoquery_result.stdout }}"
- 说明:
repoquery直接从仓库拉取版本信息,无多余操作,效率极高;同样支持通配符匹配,比如repoquery --latest java*。
内容的提问来源于stack exchange,提问作者Sir_Yaro
相关产品推荐
相关产品推荐

