我有三台 Linux 服务器,并且创建了 ansible 清单文件:
[web]
192.168.0.155
192.168.0.165
192.168.0.175
我有playbook.yml:
---
- hosts: web
tasks:
- name: Check drinks versions
shell: "python3.4 {{ item.sw_path }} -v"
sudo: yes
with_items:
- { sw_path: '/home/beer.py' }
- { sw_path: '/home/vodka.py' }
- { sw_path: '/home/whisky.py' }
脚本(beer.py、vodka.py 和 whisky.py)以如下格式打印其版本:“/home/beer.py 1.0.0”。我需要获取此版本,将其与我存储在数据库中的版本进行比较(这是实际版本),如果版本不相等,则将实际版本从 svn(svn 路径也存储在数据库中)复制到服务器。如何使用 ansible 功能做到这一点?
答案1
Ansible 没有直接检查任何程序版本的模块。您有两个选择,都涉及一个 bash 命令,用于从脚本的输出中提取版本号。这可能应该可以做到:
$program | rev | cut -d ' ' -f1 | rev
选项1:运行任务来获取版本。基本上就是您已有的内容加上版本提取。
- name: Check drinks versions
shell: "python3.4 {{ item.sw_path }} -v | rev | cut -d ' ' -f1 | rev"
sudo: yes
with_items:
- { sw_path: '/home/beer.py' }
- { sw_path: '/home/vodka.py' }
- { sw_path: '/home/whisky.py' }
register: versions
现在您有一个versions
注册的变量,并且其中versions.result
包含一个字典列表,其中包含 sw_path 和每个循环项的返回值。
像这样:
"results": [
{
"item": {
"sw_path": "/home/beer.py"
},
"stdout": "1.0.0"
},
{
"item": {
"sw_path": "/home/vodka.py"
},
"stdout": "1.0.0"
},
{
"item": {
"sw_path": "/home/whiskey.py"
},
"stdout": "1.0.0"
}
}
要查看注册数据的真实内容,请使用如下调试任务:
- debug: var=versions
选项 2:使用自定义事实
您可以在远程主机上安装一个脚本(当然使用 Ansible)来返回版本。当 Ansible 连接到这些主机时,它会自动运行这些脚本并将其用作事实,就像任何其他系统属性一样。
该脚本可以像这样简单:
#!/bin/sh
echo [versions]
echo beer=$(python3.4 /home/beer.py -v | rev | cut -d ' ' -f1 | rev)
echo vodka=$(python3.4 /home/vodka.py -v | rev | cut -d ' ' -f1 | rev)
echo whiskey=$(python3.4 /home/whiskey.py -v | rev | cut -d ' ' -f1 | rev)
输出应如下所示:
[versions]
beer=1.0.0
vodka=1.0.0
whiskey=1.0.0
您可以使用 Ansible 安装此脚本,例如使用模板模块。因此,您甚至可以根据项目列表使其动态化sw_path
。
安装后,您需要重新加载事实。您可以在模板任务之后立即使用此任务执行此操作:
- setup:
filter: ansible_local
现在您将能够直接访问版本等ansible_local.versions.beer
。
关于版本检测就说这么多。
您没有提到这一点,但我认为您知道如何从数据库中获取版本进行比较。否则,您将需要提供更多数据。因此,我们假设您将“应该的版本”存储为should["beer"]
、should["vodka"]
和should["whiskey"]
。
您现在可以将版本与版本比较筛选。
- subversion: dummy command installing {{ item }}
with_items:
- beer
- vodka
- whiskey
when: "{{ ansible_local.versions[item] | version_compare(should[item], '<') }}"
如果安装了比数据库中引用的版本更新的版本,这只会升级而不会降级。当然,您可以直接比较字符串并确保始终安装准确的版本。
when: "{{ ansible_local.versions[item] != should[item] }}"