У меня есть три Linux-сервера, и я создал доступный файл инвентаризации:
[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 и Whicky.py) печатают свои версии в следующем формате: «/home/beer.py 1.0.0». И мне нужно получить эти версии, сравнить их с версиями, которые я храню в базе данных (это фактические версии), и если версии не равны, скопируйте фактическую версию из svn (пути svn также хранятся в базе данных) на сервер. Как я могу это сделать, используя возможности ansible?
В 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
- это список dicts, который содержит 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"]
.
Теперь вы можете сравнить версии с version_compare фильтр.
- 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] }}"