Назад | Перейти на главную страницу

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

У меня есть три 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] }}"