Как я могу проверить версию программного обеспечения с Ansible?

У меня есть три сервера Linux, и я создал ANSI файл инвентаризации:

[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"],

Теперь вы можете сравнить версии с фильтром 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] }}"
Другие вопросы по тегам