如何在Ansible的Jinja模板中处理多段版本号比较?
问题描述
现有存储环境发布版本的变量release_versions,内容如下:
prod: 10.7.2 dev1: 10.8 dev2: 10.7 dev3: 10.6.2 dev4: 10.7.2 dev5: 10.7.1
需要通过Ansible的Jinja模板将各环境版本与生产环境版本对比,输出如下格式的结果,标记需要更新的环境:
dev1: 10.8 dev2: 10.7(需要更新至10.7.2) dev3: 10.6.2(需要更新至10.7.2) dev4: 10.7.2 dev5: 10.7.1(需要更新至10.7.2)
当前代码使用浮点数处理版本号,仅支持两段数字的版本(如10.7),无法适配三段版本号(如10.7.2),代码如下:
prod_db_version: "10.7.2" - copy: dest: /tmp/version.txt content: | {% for i in release_versions %} {{ i.name }}: {{ i.version }}{% if format(j.version|float) < format(prod_db_version|float) %}(need to update to {{prod_db_version}}){% endif %} {% endfor %}
解决方案
核心思路是将版本号按.分割为整数列表,利用Python列表的逐元素对比特性实现版本号的大小判断(列表会依次比较对应位置的元素,直到找到差异)。修改后的代码如下:
prod_db_version: "10.7.2" - copy: dest: /tmp/version.txt content: | {% set prod_version_list = prod_db_version.split('.') | map('int') | list %} {% for env, version in release_versions.items() %} {% if env != 'prod' %} {% set env_version_list = version.split('.') | map('int') | list %} {{ env }}: {{ version }}{% if env_version_list < prod_version_list %}(需要更新至{{ prod_db_version }}){% endif %} {% endif %} {% endfor %}
关键说明:
- 版本号转换:通过
split('.')将版本号拆分为字符串列表,再用map('int')转换为整数列表,比如"10.7.2"会转为[10,7,2],"10.7"转为[10,7]。 - 列表对比逻辑:Python列表比较会逐元素对比,例如:
[10,7] < [10,7,2]→ 结果为True(前两位相等,短列表视为更小)[10,7,1] < [10,7,2]→ 结果为True[10,8] > [10,7,2]→ 结果为False(第一位相等,第二位8>7)
- 过滤生产环境:通过
if env != 'prod'跳过生产环境的输出,符合需求格式。
内容的提问来源于stack exchange,提问作者Philip Shangguan
相关产品推荐
相关产品推荐

